Documentation updates for proposed Cobalt workflow (#244)

* changing the formatting setup of the readme and deleting the empty readme

* readjust the table of contents to move design towards the end

* some ideas for project main readme

* Refactor main project README.md to be smaller and reference other more granular README docs. Also added some high level template/module documentation.

* Adding in the main steps for the application developers - TODO adding in detailed instructions and UI images

* updating the getting started for app dev doc...Screenshots to be added

* updating the readme with the screenshots of the az devops portal steps

* Merged getting started documentation into a single feature branch to ensure coverage.

* update getting started doc

* update getting started doc

* update getting started doc

* Updates to docs; added preview feature notes and environment variable groups.

* update getting started doc

* update getting started doc

* update getting started doc

* Added initial cut of CLI version of app dev focused Getting Started

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* Updated with CLI commands

* Fixed removal of unneeded pieces.

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* update getting started doc

* Updates to CLI docs. Broke out steps into separate code blocks versus single code block.

* adding some minor changes to the app dev readme

* Moved getting started docs into new 'docs' directory.

* Updated links and resolved CLI docs comments.

* Update GETTING_STARTED_ADD_PAT_OWNER.md

* Update GETTING_STARTED_APP_DEV_CLI.md

* update getting started doc
This commit is contained in:
Megan Meyer 2019-08-27 17:43:55 -05:00 коммит произвёл GitHub
Родитель 0cbb95eef0
Коммит 1a801597e4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 743 добавлений и 77 удалений

Просмотреть файл

@ -1,92 +1,44 @@
- [Cobalt](#cobalt)
- [Getting Started](#getting-started)
- [Relationship to Bedrock](#relationship-to-bedrock)
- [Community](#community)
- [Contributing](#contributing)
# Cobalt
[![Build Status](https://dev.azure.com/csedallascrew/project-cobalt/_apis/build/status/Microsoft.cobalt?branchName=master)](https://dev.azure.com/csedallascrew/project-cobalt/_build/latest?definitionId=2&branchName=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/microsoft/cobalt)](https://goreportcard.com/report/github.com/microsoft/cobalt)
This project is an attempt to combine and share best practices when building production ready [cloud native](https://www.cncf.io/) managed service solutions. Cobalt's infrastructure turn-key starter [templates](/infra/templates/README.md) are based on real world engagements with enterprise customers.
This project combines and shares best practices for building production ready [cloud native](https://www.cncf.io/) managed service solutions. Cobalt's infrastructure turn-key starter [templates](./infra/README.md) are based on real world engagements with enterprise customers.
This project puts a focus on infrastructure scalability, security, automated testing and deployment repeatability and most importantly, developer experience. Cobalt's intended audience is for developers. Feedback and suggestions are encouraged through issue requests. We welcome contributions across any one of the major cloud providers.
Cobalt puts a focus on infrastructure scalability, security, automated testing and deployment repeatability and most importantly, developer experience. The Project's intended audience is for developers. Feedback and suggestions are encouraged through issue requests. We welcome contributions across any one of the major cloud providers.
Cobalt is a joint collaboration with project [Bedrock](https://github.com/Microsoft/bedrock).
This project offers a set of continuous integration pipelines responsible for testing and deploying templated environments to cloud provider(s).
## Infrastructure Setup: How it works
![image](https://user-images.githubusercontent.com/7635865/60480300-be8ffb80-9c4e-11e9-819a-221cea2cb93b.png)
## How Cobalt differs from Bedrock
# Getting Started
The steps for getting started depends on your high level goals. Select the correct set of instructions based on your overall use case for Cobalt.
- [Getting Started - Cobalt Developer](./docs/GETTING_STARTED_COBALT_DEV.md): Start here if you want to contribute to the Cobalt repository to create new advocated pattern templates or pipelines.
- [Getting Started - Advocated Pattern Owner](./docs/GETTING_STARTED_ADD_PAT_OWNER.md): Start here if you want to maintain advocated pattern templates from Cobalt templates within your organization. Typically this will be the first step in leveraging Cobalt at your organization.
- [Getting Started - Application Developer](./docs/GETTING_STARTED_APP_DEV_CLI.md): Start here if your organization already uses Cobalt and you want to deploy an advocated pattern to host your application.
# Relationship to Bedrock
Cobalt hosts reusable Terraform modules to scaffold managed container services like [ACI](https://docs.microsoft.com/en-us/azure/container-instances/) and [Application Services](https://docs.microsoft.com/en-us/azure/app-service/) as a couple of examples. Bedrock targets Kubernetes-based container orchestration workloads while following a [GitOps](https://medium.com/@timfpark/highly-effective-kubernetes-deployments-with-gitops-c7a0354f1446) devops flow. Cobalt templates reference Terraform modules like virtual networks, traffic manager, etc.
## About the Repository
### Infrastructure as Code
Cobalt infrastructure templates are written in Terraform and can be found in the templates [folder](infra/templates). Each subfolder represents a unique deployment schema and is packaged with a set of Terraform scripts, overview and setup instructions and automated unit & integration tests.
Each template makes use of Terraform [modules](https://www.terraform.io/docs/modules/index.html) across both Bedrock and [Cobalt](infra/modules). Cobalt's module registry is categorized by cloud provider then resource type. Each modules represents an abstraction for the set of related cloud infrastructure objects that the module will manage.
```bash
$ tree infra
├───modules
│ └───providers
│ ├───azure
│ │ ├───api-mgmt
│ │ ├───app-gateway
│ │ ├───provider
│ │ ├───service-plan
│ │ ├───tm-endpoint-ip
│ │ ├───tm-profile
│ │ └───vnet
│ └───common
└───templates
├───az-hello-world
│ └───test
│ └───integration
└───backend-state-setup
```
### Continuous Integration / Deployment + Testing
Cobalt Continuous Integration pipeline definitions are available in the `./devops/provider` folder. As of today, Cobalt provides a git devops workflow [definition](devops/providers/azure-devops/templates/azure-pipelines.yml) for Azure DevOps. We welcome pipelines from other providers like Jenkins.
#### Azure DevOps CI Flow
![image](./design-reference/devops/cobalt-devops-ci.gif)
This pipeline is configured to trigger new builds for each new PR.
1. Deployment credential secrets such as service principal and terraform remote state storage accounts are sourced in azure keyvault.
2. The pipeline downloads secrets from keyvault and used to resolve terraform template variables.
3. The test harness image will be re-built. This includes copying any changes to Terraform scripts and the associated Terraform tests.
4. The test harness container will be run. It will perform the following stages.
* Run a lint check on all golang test files and terraform templates.
* Executes all golang unit tests.
* Generate and validate the terraform plan.
* Apply the terraform template resource updates to the development integration deployment environment.
* Run end-to-end integration tests.
* Tear down deployed resources.
5. Update the build and PR status.
6. Begin code review once the PR status is green.
### Getting Started
The easiest way to try Cobalt is to start with our [hello-world](https://github.com/Microsoft/cobalt/tree/master/infra/templates/az-hello-world) template.
Setting up a cobalt deployment comprises of 5 general steps.
1. You can follow these [instructions](devops/providers/azure-devops/README.md) to create an cloud-based CI pipeline definition.
2. Our cloud deployment templates provide an configurable default setup intended for a t-shirt sized environment scenario. Pick the template folder most relevant to your use-case as a starting point. Each template folder is shipped with setup instructions.
3. It's important to implement quality assurance that validates E2E functional assertions against your infrastructure resources. Each template comes pre-packaged with some basic integration and unit tests. We encourage you to define integration tests in the `test/integration` folder of your template that's specific to your use-case.
4. Follow these [instructions](test-harness/README.md) to setup your local environment. Make sure that the repository lives in a directory that does not live within `$GOPATH`.
5. Create a new local git branch and commit your changes. Run the test harness on your localhost via `./test-harness/local-run.sh`.
## Community
# Community
[Please join us on Slack](https://publicslack.com/slacks/https-bedrockco-slack-com/invites/new) for discussion and/or questions.
## Contributing
# Contributing
We do not claim to have all the answers and would greatly appreciate your ideas and pull requests.

Просмотреть файл

Просмотреть файл

@ -1,21 +1,35 @@
# CI/CD with Azure Devops
![cobalt-ci-flow](https://user-images.githubusercontent.com/7635865/56059699-42aaa500-5d2a-11e9-8544-5236e7a9b2ef.png)
- [Background Context](#background-context)
- [Setup](#setup)
- [Prerequisites](#prerequisites)
- [CI/CD with Azure DevOps using the Azure DevOps CLI](#CI/CD-with-Azure-DevOps-using-the-Azure-DevOps-CLI)
- [CI/CD with Azure DevOps using the Azure DevOps UI](#CI/CD-with-Azure-DevOps-using-the-Azure-DevOps-UI)
- [Design Motivation](#design-motivation)
- [CI/CD Flow](#ci/cd-flow)
-[References](#references)
# Background Context
This section describes how to configure Azure Devops as the CI/CD system for your DevOPS Workflow.
## Prerequisites
# Setup
### Prerequisites
1. _Permissions_: The ability to create Projects in your Azure DevOps Organization.
2. Azure CLI installed on your [machine](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest).
## Setup
### Create a New Project in Azure DevOps using the CLI
### CI/CD with Azure DevOps using the Azure DevOps CLI
```bash
az devops project create -n $PROJECT_NAME
```
TODO
### CI/CD with Azure DevOps using the Azure DevOps UI
#### Create a new project
TODO
#### Create a Service Connection to Github
@ -60,6 +74,13 @@ Setup the below variables to the build pipeline definition.
- `TF_VAR_remote_state_account` - The terraform remote state storage account name.
- `TF_VAR_remote_state_container` - The terraform remote state storage container name.
### Reference
# Design Motivation
This section describes how to configure Azure Devops as the CI/CD system for your DevOPS Workflow.
### CI/CD Flow
![cobalt-ci-flow](https://user-images.githubusercontent.com/7635865/56059699-42aaa500-5d2a-11e9-8544-5236e7a9b2ef.png)
# References
- [Azure Pipelines](https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started/what-is-azure-pipelines?toc=/azure/devops/pipelines/toc.json&bc=/azure/devops/boards/pipelines/breadcrumb/toc.json&view=azure-devops)

Просмотреть файл

@ -0,0 +1,256 @@
# Getting Started - Advocated Pattern Owner
## Cobalt Enterprise Integration - Overview
Completion of the steps from this document results in an Azure Devops Repo initialized with carefully selected Cobalt Advocated Pattern Templates (Infrastructure as code) along with a CI/CD pipeline ready for multi-stage deployments.
This document provides Cobalt users instructions for initializing and integrating Cobalt into their existing AzureDevops organization using an Azure subscription. These steps assume some basic familiarity with the Azure DevOps portal and a desire to automate the creation of infrastructure. For more information on Cobalt, visit the following link: [READ ME](../README.md)
### Prerequisites
* An Azure Subscription
* Azure Devops Organization
* Permissions to your Organization's Azure Devops account
* *Global administrator role* permissions in your Organization's Azure Active Directory tenant to setup service principals
* If this is not allowed by your organization, step two and the Service Connection creation in step three will need to be completed by someone within your organization with this permission.
### STEPS
1. **Initialize Azure Repo Subscription with Cobalt**
This step helps setup your Azure Devops repo with Cobalt Advocated Pattern Templates that matter to you. These are common instructions that are needed for any audience interested in using Cobalt for infrastructure automation.
* Create a new project
* Sign-in to Azure DevOps (https://azure.microsoft.com/en-us/services/devops/)
* Select New project and create a name. (ex. Cobalt-Contoso)
![New Project](https://user-images.githubusercontent.com/10041279/63442791-4f868600-c3f9-11e9-91f3-c959654f5a1c.png)
* Select Create
* Create new repository by fetching source code from the master branch of Cobalt's open-source github project
* Select Repos tab within side-navigation menu
* Select 'Import a repository' from the Repos tab sub-menu and click [Import]
* Enter the Cobalt Clone URL (https://github.com/microsoft/cobalt.git) and select Import
![Clone Button](https://user-images.githubusercontent.com/10041279/63459072-8ec4cf00-c419-11e9-8ef4-ee7db827e49c.png)
* Rename your repository
* Click your Repo Name (ex. Cobalt-Contoso) at the top of the page.
![Repo Name dropdown](https://user-images.githubusercontent.com/10041279/63615290-9d8ebb80-c5aa-11e9-9136-64295640205b.png)
* Select Manage Repositories
* Under Git repositories, find "Cobalt-Contoso" and select the ellipses
* Select Rename repository
![Rename Repo dropdown](https://user-images.githubusercontent.com/10041279/63615540-3b828600-c5ab-11e9-9174-07f23b3193bf.png)
* Give it a new name and click [Rename]
| Naming Recommendation | Template Repo Strategy |
|-------------|-----------|
| Cobalt-Hello-World-Contoso | If the aim is to introduce oneself or the organization to Cobalt, we recommended a name that reflects the spirit of the Azure Hello World Cobalt template. |
| Cobalt-AZ-ISO-Contoso | If the aim is to have a single repository represent a single Cobalt template, and thereafter, to have one repo per template, we recommend a name that reflects the Cobalt Template being deployed. In this naming example, the name assumes this repo will be dedicated to deploying the Cobalt *az-isolated-service-single-region* template |
| Cobalt-Contoso | If the aim is to use a single repository as ground truth for all potential patterns across your organization, effectively having to manage a combination of Cobalt patterns from a single repo, it's recommended to stick with a name that matches the project name. |
* Initialize new Azure Devops pipeline
* Select Pipelines tab from within side-navigation menu
* Select Create Pipeline and then choose 'Azure Repos Git [YAML]'
![Pipeline Menu](https://user-images.githubusercontent.com/10041279/63459652-89b44f80-c41a-11e9-829a-05a6888b7673.png)
* Find and select the newly created repository from dropdown menu
* Import YAML by selecting 'Existing Azure Pipelines YAML file'
* Enter the path to the devops yaml file that lives within your newly created repo. (i.e. devops/providers/azure-devops/templates/azure-pipelines.yml)
![Select YAML](https://user-images.githubusercontent.com/10041279/63459938-21b23900-c41b-11e9-9b9c-2dfa72e51350.png)
> NOTE: Automatic drop-down does not always populate with yaml file options. It may be necessary to simply copy and paste the above path.
* Review devops pipeline YAML and only keep templates relevant to your enterprise patterns.
* Remove jobName configurations not relevant to your enterprise patterns. If new to Cobalt, we recommend keeping the path to the az_hello_world template as a starter template. This step can also be completed later as a code commit to your repo. Below is an example of a jobName that you may want to remove by simple deleting it.
```yaml
configurationMatrix:
- jobName: az_service_single_region
terraformTemplatePath: 'infra/templates/az-service-single-region'
terraformWorkspacePrefix: 'sr'
environmentsToTeardownAfterRelease:
- 'devint'
```
* Save and run
![Fail Screenshot](https://user-images.githubusercontent.com/10041279/63546484-8ccd3f80-c4ef-11e9-8d9f-2f06dc725fc7.png)
> NOTE: Azure Devops forces a run so expect this to fail. Future steps will resolve this problem.
2. **Provision Azure resources needed for Azure Devops pipeline**
This step sets up all the values and resources that will serve as inputs to your test automation pipeline in Azure Devops. Without this setup step, you cannot deploy Cobalt templates to Azure Devops.
* Create a registered Azure AD (AAD) app for Cobalt deployments
* Sign-in to your organization's Azure account. (https://portal.azure.com)
* Filter for Azure Active Directory and navigate to it's menu
* Select App registrations from the menu blade
* Click [Add/+] New registration then enter a name for the application (ex. cobalt-hw-admin-sp-`<username>` or cobalt-az-iso-admin-sp-`<username>`)
* Choose single tenant as a supported account type
* Click Register
* Setup permissions for the new AAD app to also use legacy API permissions
* From the App registrations service blade, select the API permissions
* Click [+ Add a permission] then use the *APIs my Organization uses* tab to search for Windows Azure Active Directory
* Configure Azure Activity Directory Application permissions to ReadWrite.OwnedBy
![Request Permissions menu](https://user-images.githubusercontent.com/10041279/63549279-b6896500-c4f5-11e9-9c92-40ac2a4295c9.png)
* Click [Add permissions] to save this configuration
* Click [Grant admin consent for *Your Directory*] to grant consent on behalf of users in this directory for this permission
* Configure the new AAD app as a Cobalt admin service-principal/service-endpoint
* From the App registrations service blade, click the [Certificates & secrets] tab
* Click [+New client secret] from within the Client secrets menu then enter a description (ex. rbac)
![Client Secret menu](https://user-images.githubusercontent.com/10041279/63461963-69d35a80-c41f-11e9-8d4a-c72235177fb3.png)
* Click Add
> IMPORTANT: Generate a secret that does not have a trailing slash. Secrets that lead with a slash (ex."/","\") may cause parsing errors.
> NOTE: Take note of the generated client secret (only displayed once). This will be used for your Azure Devops Service Connection in step 3.
* From the App registrations service blade, select Overview.
> NOTE: Take note of the Application (client) ID. This will also be used for your Azure Devops Service Connection in step 3.
* Grant newly created Service Principal an Owner role to your preferred enterprise subscription.
This elevates the Service Principal with more permissions so that Terraform can rely on this Service Principal as an Azure user for Cobalt template deployments.
* Filter for subscriptions and navigate to the subscriptions list
* Either choose a subscription or create a new one (ex. Cobalt-Contoso-Deployments)
* Select your chosen subscription then select the Access control (IAM) tab from the menu blade.
* Click [+/Add] and select Add role assignment
* From the sub-menu, select 'Owner' as a role from the drop down and search for the newly created Service Principal (i.e. cobalt-hw-admin-sp-`<username>` or cobalt-az-iso-admin-sp-`<username>`)
![Role Assignment menu](https://user-images.githubusercontent.com/31149154/63708249-7ed23400-c7f9-11e9-8dbb-c15dcdaf3a37.png)
* Click Save
* Create Resource Group and Storage Account for backend state
* Filter for Storage accounts and navigate to the storage account list
* Click [+/Add] and enter values for the following fields:
* Subscription: Your preferred enterprise subscription for Cobalt template deployments
* Resource group: Create new (ex. cobalt-devint-hw-admin-rg or cobalt-devint-az-iso-admin-rg )
* Storage account name: (ex. cobalttfstates)
* Click [Review+Create] then [Create]
* Once deployment for storage account is completed, go to the resource and visit the Blobs sub-menu
* Click [+Container] then create a container name (ex. az-hw-remote-state-container or az-iso-remote-state-container) with private access
3. **Configure Azure Devops pipeline using Azure resource values**
This step is about making sure Azure Devops references all the values and resources you took the time to create in the Azure portal.
* Add the Azure Subscription being used for Cobalt as a *Service Connection*
* Return to your Azure DevOps subscription
* Find and select the Project Settings tab at the bottom of the screen
* Under the Pipelines menu select Service Connections
* From the Service Connections menu, select [+New Service Connection]
* Choose Azure Resource Manager from the dropdown then a name for your service (ex. Cobalt Deployment Administrator-`<YourTenantName>`). The name should make sense to users and will be directly referenced in pipeline variable groups later.
* Use the full version of the service connection dialog in order to enter your service principal credentials (AAD Key, AAD App ID, Tenant, etc.)
![Service Connection menu](https://user-images.githubusercontent.com/10041279/63485304-63b59c00-c468-11e9-8e47-721a2e43ecb9.png)
* Verify and Save the connection
> NOTE: Take note of the custom name given to this service connection. This will be referenced in later steps needed to configure env variable groups.
* Enable multi-stage pipelines
* Find your signed-in avatar/image and select preview features from the drop down menu
![Preview Features menu](https://user-images.githubusercontent.com/10041279/63486065-8eedba80-c46b-11e9-90f0-7f931f909ffa.png)
* Toggle Multi-stage pipelines
* Configure *Infrastructure Pipeline Variables* as the first of two variable groups
* Select Pipelines tab from within side-navigation menu then select Library tab
* Click [+Variable group] and name it "Infrastructure Pipeline Variables"
* Add the following variables:
| Name | Value | Var Description |
|-------------|-----------|-----------|
| `AGENT_POOL` | Hosted Ubuntu 1604 | The type of build agent used for your deployment. |
| `ARM_PROVIDER_STRICT` | false | Terraform ARM provider modification |
| `BUILD_ARTIFACT_NAME` | drop | Name to identity the folder containing artifacts output by a build. |
| `GO_VERSION`| 1.12.5 | The version of Go terraform deployments are bound to. |
| `PIPELINE_ROOT_DIR` | devops/providers/azure-devops/templates/ | A path for finding Cobalt templates. |
| `REMOTE_STATE_CONTAINER` | `<CONTAINER_NAME>`| The remote blob storage container name for managing the state of a Cobalt Template's deployed infrastructure. Also is used as a naming convention for partitioning state into multiple workspaces. This name was created in an earlier step from within the azure portal. |
| `SCRIPTS_DIR` | infrastructure/scripts | Path to scripts used at runtime for composing build and release jobs at various pipeline stages. |
| `TEST_HARNESS_DIR` | test-harness/ | A path to the cobalt test harness for running integration and unit tests written in Docker and Golang. |
| `TF_ROOT_DIR`| infra | The primary path for all Cobalt templates and the modules they are composed of. |
| `TF_VERSION`| 0.12.4 | The version of terraform deployments are bound to. |
| `TF_WARN_OUTPUT_ERRORS`| 1 | The severity level of errors to report. |
> Important: Every targeted environment specified within the build pipeline expects a
> variable group specified with the naming convention `<ENVIRONMENT_NAME> Environment Variables`
* Configure *DevInt Environment Variables* as the final variable group
* Environment-specific variables have no default values and must be assigned
* Return to the Library tab
* Click [+Variable group] and name it *DevInt Environment Variables*
* Add the following variables:
| Name | Value | Var Description |
|-------------|-----------|-----------|
| `ARM_SUBSCRIPTION_ID` | `<ARM_SUBSCRIPTION_ID>` | The Azure subscription ID for which all resources will be deployed. Refer to the Azure subscription chosen in Azure portal for Cobalt deployments. |
| `REMOTE_STATE_ACCOUNT` | `<AZURE_STORAGE_ACCOUNT_NAME>` | The storage container account name created in a previous step that is used to manage the state of this deployment pipeline. The storage Account is shared among all non-prod deployment stages. |
| `SERVICE_CONNECTION_NAME` | ex. Cobalt Deployment Administrator-`<TenantName>` | The custom name of the service connection configured in a previous Azure Devops step that establishes a connection between the Service Principal and the Azure subscription that it's permissioned for. |
* Additional Setup Instructions per Template
Select Cobalt templates require additional pipeline setup. Please complete extended steps if chosen template resides in the below list.
* az-isolated-service-single-region
1. Create ASE w/ VNET
2. Add additional env vars to *Infrastructure Pipeline Variables* group
| Name | Value | Var Description |
|-------|-------|-----------------|
| `TF_DEPLOYMENT_TEMPLATE_ROOT` | infra/templates/az-isolated-service-single-region | Pipeline reference for relative location of this template |
* Link Variable Groups for DevInt and Infrastructure to the Build Pipeline
* Select Pipelines tab from within side-navigation menu
* Select existing pipeline and then click [Edit]
* Next to the [Variables] button at the top of the page, click the ellipses and select Triggers
![Triggers](https://user-images.githubusercontent.com/41071421/63284806-022fda80-c27a-11e9-8e23-494314c63651.png)
* Navigate to the [Variables] tab and begin linking each variable group
* Link each variable group, one by one
![Link Variable Groups](https://user-images.githubusercontent.com/10041279/63489261-3b816980-c477-11e9-87bf-1d254226e8fd.png)
* Save the build pipeline
4. **Clone newly created Azure DevOps Repo from your organization**
With this step, the goal is to pull down the repo into a local environment so that one can begin making code changes.
* Visit your newly created repo and clone down the repo.
![git Clone button](https://user-images.githubusercontent.com/10041279/63484822-9f4f6680-c466-11e9-8aa5-13ad9ba763d9.png)
```bash
$ git clone <insert-git-repo-url>
```
5. **Keep the templates relevant to your enterprise patterns**
The goal of this step is to continue efforts removing infrastructure as code Cobalt templates that users have no interest in deploying.
* Open the project from your favorite IDE and navigate to infrastructure templates `./infra/templates` directory.
* Manually delete template directories not needed for your enterprise.
> NOTE: Do not delete 'backend-state-setup' template! We also recommended keeping the 'az-hello-world' template as a starter template.
* Commit the newly pruned project to your newly forked repo.
```bash
$ git commit -m "Removed unrelated templates." && git push
```
> NOTE: Integration tests running in the release stage of the pipeline may have resource group level naming conflicts if other tests of the same templates are also running or have been persisted in the Azure portal.
## Conclusion
Recommended next step is to either reference containerized applications by their image name from within a Cobalt template in order to run a deployment or to employ this repo as ground truth for acceptable patterns and versioning across an organization.

Просмотреть файл

@ -0,0 +1,116 @@
# Getting Started - Application Developer
### Overview
This section provide Cobalt technical operators with a general use case Azure DevOps pipeline. Operators can import this yaml based template when creating their pipeline in the Azure DevOPS portal.
### Fork the Repository
Fork the cobalt repository that has been created. For more details on creating the initial repository, please review [Getting Started](GETTING_STARTED_ADD_PAT_OWNER.md)
Fork the repository in either github or Azure DevOps
![image](https://user-images.githubusercontent.com/41071421/63653594-87146b80-c734-11e9-9282-ab9e8f874b83.png)
### Add Branching Strategy
Add the branching strategy on the newly created fork to ensure the branches are protected. Branch Strategy can be added in Github or Azure DevOps Repo section directly
#### Git: Master Branch Policies for IAC Repo
We strongly recommend adding branch policies to help protect the master branch and configure mandatory validation builds to avoid simultaneous builds when merging into master.
![image](https://user-images.githubusercontent.com/7635865/60196805-97c36680-9803-11e9-9fd0-7bedc34fc9ad.png)
Here's some more [guidance](https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github?view=azure-devops&tabs=yaml#protecting-branches) on leveraging Azure DevOPS build validation checks with protected branch's.
#### Recommended Branch Policies
- ✅ Do - Require pull request reviews before merging.
- ✅ Do - Prevent force pushing e.g. to prevent rewriting the commit history.
- ✅ Do - Require completion of Production stage release in Azure DevOPS before merging.
- ✅ Do - Prevent parallel releases into QA, staging and production environments.
- ✅ Do - Require status checks to pass before merging changes into the protected branch.
### Choose an existing project
If a project has not been created within an organization, please refer to [Getting Started](GETTING_STARTED_ADD_PAT_OWNER.md) on directions to create a project.
![Select a Project](https://user-images.githubusercontent.com/41071421/63275190-af005c80-c266-11e9-9241-118f527551f4.png)
### Create a New Pipeline
#### Select Pipelines on the left
![Select Pipeline](https://user-images.githubusercontent.com/41071421/63275297-ea029000-c266-11e9-9288-33e34ee2e033.png)
#### Create new Pipeline
![Create New Pipeline](https://user-images.githubusercontent.com/41071421/63275363-08688b80-c267-11e9-9fba-3022b3ac94a2.png)
#### Select Github as the source
![Choose Github](https://user-images.githubusercontent.com/41071421/63277498-102a2f00-c26b-11e9-87e4-167af2fafed0.png)
#### Choose the forked project
![Select the Forked Repo](https://user-images.githubusercontent.com/41071421/63281118-a95c4400-c271-11e9-9265-046eb2b2c804.png)
#### Configure the Pipeline and point the build definition to the repository's target yaml pipeline location
![Configure Pipeline](https://user-images.githubusercontent.com/41071421/63281246-e4f70e00-c271-11e9-861e-2c927a3e609b.png)
#### Add in the relative path to the target YAML pipeline location
> Note: The dropdown to select the YAML file path may not auto populate so a copy and paste of the relative path from the repository may be required.
![Select YAML Path](https://user-images.githubusercontent.com/41071421/63281630-be85a280-c272-11e9-9ff9-6e9a6ba73b82.png)
### Review your Pipeline and Run
![Review Pipeline](https://user-images.githubusercontent.com/41071421/63282088-af532480-c273-11e9-8e35-e7c425f2aee3.png)
Modify any changes as needed in the YAML and hit "Run". This is needed to initially save the YAML template.
> Note: Build may initially fail until we finish the other steps.
1. Go to the Pipeline that was created and hit "Edit"
![Edit Pipeline](https://user-images.githubusercontent.com/41071421/63284395-18896680-c279-11e9-95b7-bfad4d2d6a34.png)
2. Setup the variables needed by clicking "Triggers"
![Triggers](https://user-images.githubusercontent.com/41071421/63284806-022fda80-c27a-11e9-8e23-494314c63651.png)
3. Setup and link the variable groups
Select the Variables groups and hit "Link variable group"
![Variable Groups](https://user-images.githubusercontent.com/41071421/63284674-aebd8c80-c279-11e9-802a-c4d20b4835ea.png)
Link the variable groups for DevInt, QA and Infrastructure one by one
![Link Variable Groups](https://user-images.githubusercontent.com/41071421/63285023-74a0ba80-c27a-11e9-936c-be93bc8c1048.png)
4. Save Variables
Drop down into the options for "Save & queue" and select "Save" and hit "Save" to save this build pipeline.
![Save Build](https://user-images.githubusercontent.com/41071421/63285205-e11bb980-c27a-11e9-8f3d-02a407f67075.png)
Hit "Queue" and then "Run" to start the build
> Note: a specific commit can be picked from the selected branch, if nothing is added to the commit text box, it will default to the latest commit.
![Start Build](https://user-images.githubusercontent.com/41071421/63285392-3b1c7f00-c27b-11e9-9bcb-92af0cd8789e.png)
The build will run through the stages and upon select a stage, more details will be presented on what the build is doing
![Stages for Build](https://user-images.githubusercontent.com/41071421/63285564-9fd7d980-c27b-11e9-8a9f-7835f6244339.png)
![Build Details](https://user-images.githubusercontent.com/41071421/63285648-d57cc280-c27b-11e9-916f-901185b2d97f.png)
Upon a successful build, all jobs will be marked off in green and shown as completed
![Successful Build](https://user-images.githubusercontent.com/41071421/63285815-399f8680-c27c-11e9-85c3-babffd75282b.png)
> Note: you may need to enable the experimental feature to allow multi-stage build pipelines if your view does not show the stages of the build pipeline. Directions for enabling preview features are available [here](https://docs.microsoft.com/en-us/azure/devops/project/navigation/preview-features?view=azure-devops).

Просмотреть файл

@ -0,0 +1,199 @@
# Getting Started - Application Developer - Azure CLI
*Prefer using portals? Follow the [portal-based walkthrough](./GETTING_STARTED_APP_DEV.md).*
## Overview
This section provides application developers wishing to host solutions on Cobalt templates recommendations for building their infrastructure-as-code repository and accompanying CI/CD pipelines. It assumes an isolated Azure DevOps Project with a Cobalt template Repo and Build Pipeline has already been created as defined in the [Getting Started - Advocated Pattern Owner](./GETTING_STARTED_ADD_PAT_OWNER.md) walkthrough.
By creating an application-specific project, you are creating a single project supporting the two main pillars of an application -- the Cobalt-template-based infrastructure and CI/CD build pipeline, and the application code and CI/CD build pipeline. **Important**: as an application developer, you will not be modifying the Cobalt template even though you will be importing all of the required code into your project repository. Instead, you will be responsible only for modifying the configuration via the template's `terraform.tfvars` file to support your application's unique settings (e.g., the number of deployment targets to create or Azure Container Registry image URLs).
There may be many applications forking from a single governed organization-specific Cobalt template, and requested changes should be made to the source Cobalt template repository so that all applications may update to the latest when needed.
## Prerequisites
* Azure CLI
* [Get started with Azure CLI](https://docs.microsoft.com/en-us/cli/azure/get-started-with-azure-cli?view=azure-cli-latest)
* Azure DevOps CLI extension
* [Get started with Azure DevOps CLI](https://docs.microsoft.com/en-us/azure/devops/cli/get-started?view=azure-devops)
* Existing repository and CI/CD pipeline for desired Cobalt template
* [Getting Started - Advocated Pattern Owner](./GETTING_STARTED_ADD_PAT_OWNER.md)
## Steps
### 1. Setup Environment Variables
Define variables for ease of execution of snippets below.
| Variable | Sample Value | Description |
|----------|--------------|-------------|
| `APP_DEVOPS_PROJECT_NAME` | `My Application` | The name of the project representing your application that could include both your Cobalt foundation in addition to any application code, pipelines, boards, or artifacts. |
| `APPS_DEVOPS_INFRA_REPO_NAME` | `infrastructure` | The name of the repo that will be created in the application Azure DevOps project to host the Cobalt template. |
| `APP_DEVOPS_INFRA_YML_PATH` | `devops/providers/azure-devops/templates/azure-pipelines.yml` | The path relative to the `APPS_DEVOPS_INFRA_REPO_NAME` root that contains the Cobalt template pipeline to be created for provisioning application resources. |
| `DEFAULT_ORGANIZATION` | `https://dev.azure.com/MyOrganization/` | The full URL path of the organization in which your `APP_DEVOPS_PROJECT_NAME` resides or will be created. |
| `GIT_SOURCE_URL` | `https://dev.azure.com/MyOrganization/MyProject/_git/MyCobaltTemplateRepo` | The Git clone URL for the repository hosting the Cobalt template on which your project will be built. |
Update these values for your environment and application based on the guidance in the table above.
```bash
export APP_DEVOPS_PROJECT_NAME=""
export APP_DEVOPS_INFRA_REPO_NAME=""
export APP_DEVOPS_INFRA_YML_PATH=""
export DEFAULT_ORGANIZATION=""
export GIT_SOURCE_URL=""
```
The following values are used like constants and should not need to change (unless the build pipeline definition is modified).
```bash
export COBALT_VAR_GROUP_INFRA="Infrastructure Pipeline Variables"
export COBALT_VAR_GROUP_ENV_SUFFIX="Environment Variables"
export COBALT_PIPELINE_NAME="Cobalt CICD Pipeline"
```
> NOTE: Before you can run Azure DevOps CLI commands, you need to run the login command (`az login` if using AAD/MSA identity else `az devops login` if using PAT token) to setup credentials. Please see https://aka.ms/azure-devops-cli-auth for more information.
### 2. Setup Azure DevOps Project
Set your organization as the default organization for all subsequent Azure DevOps CLI commands.
```bash
az devops configure -d organization="$DEFAULT_ORGANIZATION"
```
If you already have a project for your application, you may choose to skip this step. If you need to create a new Azure DevOps project, execute the following command.
```bash
az devops project create --name "$APP_DEVOPS_PROJECT_NAME"
```
Whether you are using an existing project or just created one, set your project as the default project for all subsequent Azure DevOps CLI commands.
```bash
az devops configure -d project="$APP_DEVOPS_PROJECT_NAME"
```
### 3. Setup Azure DevOps Repo for Cobalt source
Create a new repository for the Cobalt source within your application project. Import the source from your organizational Cobalt template repository as created in the [Getting Started - Advocated Patterns Owner](./GETTING_STARTED_ADD_PAT_OWNER.md).
```bash
az repos create --name "$APP_DEVOPS_INFRA_REPO_NAME"
az repos import create --git-url $GIT_SOURCE_URL --repository "$APP_DEVOPS_INFRA_REPO_NAME"
```
> NOTE: The `az repos import` command only works with public Git repositories at the time this walkthrough was last updated. If the source template repository is private, you can manually import the source repository. This operation requires a temporary local clone of the private repository. To locally clone the private Git repository, you may need to create a Personal Access Token with permissions to clone. Additionally, if the target repository (within the newly created project) is also private, you may need to create a Personal Access Token with permissions to push to the new repository. For the purposes of this walkthrough, we recommend creating public repositories.
>
> If private repositories are required, the following steps will support the manual process.
>
> ```bash
> # Set the (new) target repository URL
> GIT_TARGET_URL=$(az repos show -r $APP_DEVOPS_INFRA_REPO_NAME --query webUrl)
>
> mkdir temprepo
> cd temprepo
>
> # Clone the private repo to a temp local directory
> git clone --bare $GIT_SOURCE_URL .
>
> # Copy the source repo to the target repo
> git push --mirror $GIT_TARGET_URL
>
> # (Optional) If the source repo has LFS objects, fetch and copy to target repo
> # git lfs fetch origin --all
> # git lfs push --all $GIT_TARGET_URL
>
> # Delete temporary folder with local clone
> cd ..
> rm -rf temprepo
> ```
>
> This approach depends on native Git commands. More information available at the [Microsoft site](https://docs.microsoft.com/en-us/azure/devops/repos/git/import-git-repository?view=azure-devops#manually-import-a-repo), or [Github forking](https://help.github.com/en/articles/fork-a-repo).
### 4. Setup Azure DevOps CI/CD Build Pipeline for Cobalt
Create the build pipeline. We are intentionally skipping the initial run since we know it will fail; we need to link the required variables groups to this pipeline, and currently that cannot be done directly through the Azure DevOps CLI.
```bash
az pipelines create --name "$COBALT_PIPELINE_NAME" --repository "$APP_DEVOPS_INFRA_REPO_NAME" --branch master --repository-type tfsgit --yml-path $APP_DEVOPS_INFRA_YML_PATH --skip-run true
```
Variable groups are utilized by the pipeline to configure how the Cobalt template will be tested and deployed. The `az pipelines variable-group create` `--variables` flag expects a list of space-delimited key value pairs (e.g., `KEY1='val1' KEY2=true`).
The following *Infrastructure Pipeline Variables* are used by all possible environment-specific executions for the Cobalt pipelines.
```bash
# IMPORTANT: Replace these values as necessary to fit your environment.
az pipelines variable-group create --authorize true --name "$COBALT_VAR_GROUP_INFRA" --variables \
AGENT_POOL='Hosted Ubuntu 1604' \
ARM_PROVIDER_STRICT=true \
BUILD_ARTIFACT_NAME='drop' \
BUILD_ARTIFACT_PATH_ALIAS='artifact' \
GO_VERSION='1.12.5' \
PIPELINE_ROOT_DIR='devops/providers/azure-devops/templates/infrastructure' \
REMOTE_STATE_CONTAINER='BACKENDSTATECONTAINERNAME' \
SCRIPTS_DIR='scripts' \
TEST_HARNESS_DIR='test-harness/' \
TF_DEPLOYMENT_TEMPLATE_ROOT='infra/templates/az-hello-world' \
TF_DEPLOYMENT_WORKSPACE_PREFIX='PROJECTDEPLOYMENTWORKSPACEPREFIX' \
TF_ROOT_DIR='infra' \
TF_VERSION='0.12.4' \
TF_WARN_OUTPUT_ERRORS=1
```
> NOTE: The TF_DEPLOYMENT_TEMPLATE_ROOT and TF_DEPLOYMENT_WORKSPACE_PREFIX values are not used by all templates. If targeting the Isolated Service Single Region template, you will want to set these values; however, they will not have an effect on the Hello World template.
Within the pipeline build definition you may specify the number of environments that will be targed for deployment. For each environment specified, you will need a variable group that defines the Azure Subscription ID to where the infrastructure will be provisioned. You will also need to set a Service Connection that has permissions to provision resources on that subscription.
For this walkthrough, we will only create a single environment -- *devint*. The following commands will create the required *DevInt Environment Variables* variable group.
```bash
# IMPORTANT: Replace these values as necessary to fit your environment.
DEVINT_VAR_GROUP="DevInt $COBALT_VAR_GROUP_ENV_SUFFIX"
az pipelines variable-group create --authorize true --name $DEVINT_VAR_GROUP --variables \
ARM_SUBSCRIPTION_ID='TARGETSUBSCRIPTIONID' \
REMOTE_STATE_ACCOUNT='BACKENDSTATESTORAGEACCOUNTNAME' \
SERVICE_CONNECTION_NAME='SERVICECONNECTIONNAME'
```
> NOTE: The Service Connection name should be provided by someone in your organziation with the *Global administrator* permission for your Azure Active Directory tenant. If it has not been provisisioned for you, you may create another by following the directions outlined in the [Getting Started - Advocated Pattern Onwer documentation](./GETTING_STARTED_ADD_PAT_OWNER.md)
At this time, the Azure DevOps CLI does not support linking variable groups to pipelines. We have a temporary workaround utilizing the Azure DevOps `invoke` command to directly call the Azure DevOps REST API to update the build definition.
Write the current value of the build pipeline definition to a temporary local file, and save the PIPELINE_ID.
```bash
az pipelines show --name "$COBALT_PIPELINE_NAME" -o json > builddef.json
PIPELINE_ID=$(az pipelines show --name "$COBALT_PIPELINE_NAME" --query id)
```
Execute the list command to find the Variable Group IDs. Make note of the IDs as they will need to be added to the build pipeline definition.
```bash
az pipelines variable-group list
```
For the workaround, you'll be manually editing the builddef.json file to add the variable group references. At the end of the file, you should see the line `"variableGroups" : null`. Replace the value with the following, replacing the variable group ID placeholders (`0`) with those from the above command for the Infrastructure Pipeline Variables group and DevInt Environment Variables group:
```bash
"variableGroups": [
{ "id": 0 },
{ "id": 0 }
],
```
Save the file. Use the az devops invoke command to update the pipeline build definition with the linked variable groups.
```bash
az devops invoke --http-method PUT --area build --resource definitions --route-parameters project="$APP_DEVOPS_PROJECT_NAME" definitionId=$PIPELINE_ID --in-file builddef.json
```
### 5. Run and verify
Queue a pipeline to run.
```bash
az pipelines run --name "$COBALT_PIPELINE_NAME"
```
Because you have cloned a pipeline definition that was created from the [Getting Started - Advocated Pattern Owner](./GETTING_STARTED_ADD_PAT_OWNER.md) walkthrough, the pipeline definition may be setup to tear down the infrastructure provisioned. For this step in the end-to-end process, we would like the environment to be durable and persist beyond the pipeline execution. Check the primary `azure-pipelines.yml` file's stages. Verify that the `configurationMatrix` does not include an `environmentsToTeardownAfterRelease` property. If it does, remove it so that the environment remains available for use by the application after the pipeline succeeds.
To host your application on this provisioned environment, update the `*.tfvars` file specific to your template to ensure your application is being deployed to the infrastructure. You may also need to add values to your provisioned Azure Key Vault resource for the application to work as expected.
## Outcomes
After completing these steps, you should have an Azure DevOps Project for your application that contains:
* An Azure DevOps Repo for your application's Cobalt template infrastructure
* An Azure DevOps Build CI/CD Pipeline for your application's Cobalt template infrastructure including successful deployment and provisioning of template resources
* Provisioned durable resources available in your target Azure Subscription
## Additional Recommendations
We recommend creating a separate repository in the same shared application project for your application code. Additionally, an application CI / CD build pipeline should be created to manage the application -- executing tests, building a container, and deploying the container to the Cobalt-provisioned Azure Container Registry. The application project would then have two pillars -- one supporting the Cobalt template infrastructure configuration specific to the application, and one supporting the application development.

Просмотреть файл

@ -0,0 +1,69 @@
- [About the Repository](#about-the-repository)
- [Infrastructure as Code](#infrastructure-as-code)
- [Continuous Integration / Deployment + Testing](#continuous-integration--deployment--testing)
- [Azure DevOps CI Flow](#azure-devops-ci-flow)
- [Deploying your first template](#deploying-your-first-template)
# About the Repository
## Infrastructure as Code
Cobalt infrastructure templates are written in Terraform and can be found in the templates [folder](infra/templates). Each subfolder represents a unique deployment schema and is packaged with a set of Terraform scripts, overview and setup instructions and automated unit & integration tests.
Each template makes use of Terraform [modules](https://www.terraform.io/docs/modules/index.html) across both Bedrock and [Cobalt](infra/modules). Cobalt's module registry is categorized by cloud provider then resource type. Each modules represents an abstraction for the set of related cloud infrastructure objects that the module will manage.
```bash
$ tree infra
├───modules
│ └───providers
│ ├───azure
│ │ ├───api-mgmt
│ │ ├───app-gateway
│ │ ├───provider
│ │ ├───service-plan
│ │ ├───tm-endpoint-ip
│ │ ├───tm-profile
│ │ └───vnet
│ └───common
└───templates
├───az-hello-world
│ └───test
│ └───integration
└───backend-state-setup
```
## Continuous Integration / Deployment + Testing
Cobalt Continuous Integration pipeline definitions are available in the `./devops/provider` folder. As of today, Cobalt provides a git devops workflow [definition](devops/providers/azure-devops/templates/infrastructure/azure-pipelines.yml) for Azure DevOps. We welcome pipelines from other providers like Jenkins.
### Azure DevOps CI Flow
![image](./design-reference/devops/providers/azure/cobalt-devops-ci.gif)
This pipeline is configured to trigger new builds for each new PR.
1. Deployment credential secrets such as service principal and terraform remote state storage accounts are sourced in azure keyvault.
2. The pipeline downloads secrets from keyvault and used to resolve terraform template variables.
3. The test harness image will be re-built. This includes copying any changes to Terraform scripts and the associated Terraform tests.
4. The test harness container will be run. It will perform the following stages.
* Run a lint check on all golang test files and terraform templates.
* Executes all golang unit tests.
* Generate and validate the terraform plan.
* Apply the terraform template resource updates to the development integration deployment environment.
* Run end-to-end integration tests.
* Tear down deployed resources.
5. Update the build and PR status.
6. Begin code review once the PR status is green.
# Deploying your first template
The easiest way to try Cobalt is to start with our [hello-world](https://github.com/Microsoft/cobalt/tree/master/infra/templates/az-hello-world) template.
Setting up a cobalt deployment comprises of 5 general steps.
1. You can follow these [instructions](devops/providers/azure-devops/README.md) to create an cloud-based CI pipeline definition.
2. Our cloud deployment templates provide an configurable default setup intended for a t-shirt sized environment scenario. Pick the template folder most relevant to your use-case as a starting point. Each template folder is shipped with setup instructions.
3. It's important to implement quality assurance that validates E2E functional assertions against your infrastructure resources. Each template comes pre-packaged with some basic integration and unit tests. We encourage you to define integration tests in the `test/integration` folder of your template that's specific to your use-case.
4. Follow these [instructions](test-harness/README.md) to setup your local environment. Make sure that the repository lives in a directory that does not live within `$GOPATH`.
5. Create a new local git branch and commit your changes. Run the test harness on your localhost via `./test-harness/local-run.sh`.

Просмотреть файл

@ -0,0 +1,53 @@
- [Cobalt Templates](#cobalt-templates)
- [Cobalt Modules](#cobalt-modules)
- [Directory Structure](#directory-structure)
# Cobalt Templates
Templates are the implementation of *Advocated Patterns.* The scope of a template typically covers most of if not all of the infrastructure required to host an application and may provision resources in multiple cloud provider. Templates compose modules to create an advocated pattern. They are implemented as [Terraform Modules](https://www.terraform.io/docs/configuration/modules.html) so that they can be composed if needed, though it is more commonly the case that they need not be composed.
# Cobalt Modules
Modules are the building blocks of templates. A module is a thin wrapper that enable simple common-sense configuration of related resources (typically 1-3 but sometimes more) within a cloud provider. These modules are implemented as [Terraform Modules](https://www.terraform.io/docs/configuration/modules.html).
# Directory Structure
The directory structure of Cobalt enalbes contributions for a variety of cloud providers.
```bash
$ tree -d
.
├── modules
│ └── providers
│ └── azure
│ ├── api-mgmt
│ ├── app-gateway
│ ├── app-insights
│ ├── app-monitoring
│ ├── app-service
│ ├── container-registry
│ ├── cosmosdb
│ ├── keyvault
│ ├── keyvault-cert
│ ├── keyvault-policy
│ ├── provider
│ ├── service-plan
│ ├── service-principal
│ ├── storage-account
│ └── traffic-manager
└── templates
├── az-hello-world
│ └── tests
│ ├── integration
│ └── unit
├── az-isolated-service-single-region
│ ├── docs
│ └── tests
│ ├── integration
│ └── unit
├── az-service-single-region
│ └── tests
│ ├── integration
│ └── unit
└── backend-state-setup
```

Просмотреть файл

Просмотреть файл