{"id":13707241,"url":"https://github.com/microsoft/terraform-azure-devops-starter","last_synced_at":"2025-05-06T00:30:44.898Z","repository":{"id":52114557,"uuid":"243330549","full_name":"microsoft/terraform-azure-devops-starter","owner":"microsoft","description":"A starter project for Azure DevOps Pipelines deploying resources on Terraform.","archived":true,"fork":false,"pushed_at":"2023-05-31T10:52:29.000Z","size":2934,"stargazers_count":168,"open_issues_count":4,"forks_count":148,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-30T12:49:50.157Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/microsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-02-26T18:03:57.000Z","updated_at":"2025-04-14T23:32:57.000Z","dependencies_parsed_at":"2024-01-14T20:34:33.139Z","dependency_job_id":null,"html_url":"https://github.com/microsoft/terraform-azure-devops-starter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fterraform-azure-devops-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fterraform-azure-devops-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fterraform-azure-devops-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fterraform-azure-devops-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/microsoft","download_url":"https://codeload.github.com/microsoft/terraform-azure-devops-starter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252598188,"owners_count":21774218,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T22:01:25.141Z","updated_at":"2025-05-06T00:30:43.618Z","avatar_url":"https://github.com/microsoft.png","language":"HCL","funding_links":[],"categories":["HCL"],"sub_categories":[],"readme":"---\npage_type: sample\nproducts:\n- devops\ndescription: \"Starter project for Azure Pipelines deploying resources on Terraform\"\n---\n\n# Terraform starter project for Azure Pipelines\n\n\u003c!-- \nGuidelines on README format: https://review.docs.microsoft.com/help/onboard/admin/samples/concepts/readme-template?branch=master\n\nGuidance on onboarding samples to docs.microsoft.com/samples: https://review.docs.microsoft.com/help/onboard/admin/samples/process/onboarding?branch=master\n\nTaxonomies for products and languages: https://review.docs.microsoft.com/new-hope/information-architecture/metadata/taxonomies?branch=master\n--\u003e\n\nThis project can be used as a starter for Azure Pipelines deploying resources on Terraform.\n\n![pipeline jobs](/docs/images/terraform_starter/pipeline_jobs.png)\n\n## Contents\n\n| File/folder             | Description                                                  |\n|-------------------------|--------------------------------------------------------------|\n| `infrastructure`        | YAML pipeline templates shared across the samples.           |\n| `101-terraform-job`     | Sample YAML pipeline for a simple Terraform job.             |\n| `201-plan-apply-stages` | Sample YAML pipeline for manually approving plans.           |\n| `301-deploy-agent-vms`  | Sample YAML pipeline for deploying build agent VMs.          |\n| `docs`                  | Resources related to documentation.                          |\n| `CODE_OF_CONDUCT.md`    | Microsoft Open Source Code of Conduct.                       |\n| `LICENSE`               | The license for the sample.                                  |\n| `README.md`             | This README file.                                            |\n| `SECURITY.md`           | Reporting security issues.                                   |\n\n# Templates\n\n## 101 Basic Terraform job\n\nThe first template shows how to build an environment from Terraform configuration, and run\na subsequent job configured from Terraform outputs.\n\n[101-terraform-job: Basic Terraform job](101-terraform-job)\n\n![pipeline job](/docs/images/terraform_starter/101-terraform-job.png)\n\n## 201 Separate Plan and Apply stages\n\nThe next template shows how to build a multi-stage pipeline\nallowing to manually review and approve infrastructure changes before they are deployed.\n\n[201-plan-apply-stages: Separate Plan and Apply stages](201-plan-apply-stages)\n\n![pipeline jobs](docs/images/terraform_starter/pipeline_stage_waiting.png)\n\n## 301 Deploy hosted agent VMs\n\nThe next template shows how to use Terraform to deploy a pool of agent VMs on which to run\nsubsequent jobs.\n\n[301-deploy-agent-vms: Deploy hosted agent VMs](301-deploy-agent-vms)\n\n![agent job](/docs/images/terraform_starter/301-agent-job.png)\n\n# How to use the templates\n\n## Variables and state management\n\nVariables can be injected using `TF_VAR_` syntax in the `TerraformEnvVariables` parameter or the\n`-var key=value` syntax in the `TerraformArguments` parameter.\nThe pipelines demonstrates this by adding a custom tag named `department` to the\ncreated resource group, with distinct values in staging and QA.\n\nRather than passing a Terraform plan between stages (which would contain clear-text secrets),\nthe pipeline in the\n[201-plan-apply-stages](201-plan-apply-stages) sample\nperforms `terraform plan` again before applying changes and verifies that\na textual representation of the plan (not including secrets values) is unchanged.\n\nThe Terraform state is managed in a Azure Storage backend. Note that this backend contains\nsecrets in cleartext.\n\n## Secrets management\n\n### Generate secrets with Terraform\n\nTo demonstrate one approach to secrets management, the Terraform configuration\ngenerates a random password (per stage) for the SQL Server 1 instance, stored in\nTerraform state.\nYou can adapt this to suit your lifecycle.\n\n### Manage secrets with Azure DevOps\n\nYou might want to read credentials from an externally managed Key Vault\nor inject them via pipeline variables. This approach is demonstrated\nby defining a password for the SQL Server 2 instance and passing\nit to Terraform via an environment variable.\n\n## Getting started\n\nIn `infrastructure/terraform/variables.tf`, change the `appname` default value from\n`starterterraform` to a globally unique name.\n\n## Azure DevOps pipeline\n\nInstall the [Terraform extension for Azure DevOps](https://marketplace.visualstudio.com/items?itemName=ms-devlabs.custom-terraform-tasks).\n\nCreate a Service Connection of type Azure Resource Manager at subscription scope. Name the Service Connection `Terraform`.\nAllow all pipelines to use the connection.\n\nIn `infrastructure/terraform-init-template.yml`, update the `TerraformBackendStorageAccount` name to a globally unique storage account name.\nThe pipeline will create the storage account.\n\nCreate a build pipeline referencing `101-terraform-job/azure-pipelines.yml`.\n\n## Usage on non-master branch\n\nTo avoid issues with concurrent access to the Terraform state file, the jobs running Terraform `plan` and `apply` commands\nrun by default only on the `master` branch. On other branches, they are skipped by default:\n\n![run on non-master branch](/docs/images/terraform_starter/non_master_branch.png)\n\nYou can set the `RUN_FLAG_TERRAFORM` variable (to any non-empty value)\nwhen running the pipeline, to trigger Terraform application on a non-`master` branch.\n\n## Local development\n\nIn local development, no backend is configured so a local backend is used.\n\nInstall Azure CLI and login. Terraform will use your Azure CLI credentials.\n\n```\n$ az login -o table\nYou have logged in. Now let us find all the subscriptions to which you have access...\nCloudName    IsDefault    Name                                                  State    TenantId\n-----------  -----------  ----------------------------------------------------  -------  ------------------------------------\nAzureCloud   True         My Azure subscription                                 Enabled  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\nAzureCloud   False        My other Azure subscription                           Enabled  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n```\n\nRun `terraform init`.\n\n```\n$ terraform init\n\nInitializing the backend...\n\nInitializing provider plugins...\n- Checking for available provider plugins...\n- Downloading plugin for provider \"azurerm\" (hashicorp/azurerm) 1.38.0...\n\nTerraform has been successfully initialized!\n\nYou may now begin working with Terraform. Try running \"terraform plan\" to see\nany changes that are required for your infrastructure. All Terraform commands\nshould now work.\n\nIf you ever set or change modules or backend configuration for Terraform,\nrerun this command to reinitialize your working directory. If you forget, other\ncommands will detect it and remind you to do so if necessary.\n```\n\nRun `terraform plan`.\n\n```\n$ terraform plan -out tfplan\nRefreshing Terraform state in-memory prior to plan...\nThe refreshed state will be used to calculate this plan, but will not be\npersisted to local or remote state storage.\n\ndata.azurerm_client_config.current: Refreshing state...\n\n------------------------------------------------------------------------\n\nAn execution plan has been generated and is shown below.\nResource actions are indicated with the following symbols:\n  + create\n\nTerraform will perform the following actions:\n\n  # azurerm_resource_group.main will be created\n  + resource \"azurerm_resource_group\" \"main\" {\n      + id       = (known after apply)\n      + location = \"northeurope\"\n      + name     = \"rg-starterterraform-dev-main\"\n      + tags     = (known after apply)\n    }\n\nPlan: 1 to add, 0 to change, 0 to destroy.\n```\n\nRun `terraform apply tfplan`.\n\n```\n$ terraform apply tfplan\ndata.azurerm_client_config.current: Refreshing state...\n\nAn execution plan has been generated and is shown below.\nResource actions are indicated with the following symbols:\n  + create\n\nTerraform will perform the following actions:\n\n  # azurerm_resource_group.main will be created\n  + resource \"azurerm_resource_group\" \"main\" {\n      + id       = (known after apply)\n      + location = \"northeurope\"\n      + name     = \"rg-starterterraform-dev-main\"\n      + tags     = (known after apply)\n    }\n\nPlan: 1 to add, 0 to change, 0 to destroy.\n\nDo you want to perform these actions?\n  Terraform will perform the actions described above.\n  Only 'yes' will be accepted to approve.\n\n  Enter a value: yes\n\nazurerm_resource_group.main: Creating...\nazurerm_resource_group.main: Creation complete after 1s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/rg-starterterraform-dev-main]\n\nApply complete! Resources: 1 added, 0 changed, 0 destroyed.\n\nOutputs:\n\nsubscription_id = xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n```\n\nAt this stage you will have a new resource group deployed named `rg-starterterraform-dev-main`. \n\n# Using Terraform outputs\n\nThe pipeline automatically exports Terraform outputs into pipeline variables.\n\nThe pipelines contain a sample job that consumes those variables:\n\n![output variables](/docs/images/terraform_starter/output_variables.png)\n\n- For example, in the template [301-deploy-agent-vms](301-deploy-agent-vms), the Terraform config has an output named [agent_vm_ids](301-deploy-agent-vms/terraform/outputs.tf). In the subsequent task used\nwe use the bash variable [AGENT_VM_IDS](301-deploy-agent-vms/terraform-stages-template.yml) to pass the list of agent VMs to the `az start` command.\n\nThis mechanism is useful for using generated resource names, access keys,\nand even [entire kube_config files](https://www.terraform.io/docs/providers/azurerm/r/kubernetes_cluster.html#kube_config_raw) (for Azure Kubernetes Service)\nin downstream testing or continuous delivery jobs.\n\n# Next steps\n\n* You can of course adapt the pipeline to other environments, such as Production.\n\n## Contributing\n\nThis project welcomes contributions and suggestions.  Most contributions require you to agree to a\nContributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us\nthe rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.\n\nWhen you submit a pull request, a CLA bot will automatically determine whether you need to provide\na CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions\nprovided by the bot. You will only need to do this once across all repos using our CLA.\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).\nFor more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or\ncontact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2Fterraform-azure-devops-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicrosoft%2Fterraform-azure-devops-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2Fterraform-azure-devops-starter/lists"}