https://github.com/Azure-Samples/terraform-github-actions
A reference implementation of using GitHub Actions to deploy infrastructure to Azure using Terraform
https://github.com/Azure-Samples/terraform-github-actions
Last synced: 5 months ago
JSON representation
A reference implementation of using GitHub Actions to deploy infrastructure to Azure using Terraform
- Host: GitHub
- URL: https://github.com/Azure-Samples/terraform-github-actions
- Owner: Azure-Samples
- License: mit
- Created: 2022-10-19T19:21:38.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-07-10T14:13:34.000Z (9 months ago)
- Last Synced: 2024-08-03T22:19:30.623Z (8 months ago)
- Language: HCL
- Size: 17.6 KB
- Stars: 116
- Watchers: 17
- Forks: 130
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
- Code of conduct: .github/CODE_OF_CONDUCT.md
Awesome Lists containing this project
- jimsghstars - Azure-Samples/terraform-github-actions - A reference implementation of using GitHub Actions to deploy infrastructure to Azure using Terraform (HCL)
README
# GitHub Actions Workflows for Terraform
This is a sample repository that shows how to use GitHub Actions workflows to manage Azure infrastructure with Terraform.
## Architecture
## Dataflow
1. Create a new branch and check in the needed Terraform code modifications.
2. Create a Pull Request (PR) in GitHub once you're ready to merge your changes into your environment.
3. A GitHub Actions workflow will trigger to ensure your code is well formatted, internally consistent, and produces secure infrastructure. In addition, a Terraform plan will run to generate a preview of the changes that will happen in your Azure environment.
4. Once appropriately reviewed, the PR can be merged into your main branch.
5. Another GitHub Actions workflow will trigger from the main branch and execute the changes using Terraform.
6. A regularly scheduled GitHub Action workflow should also run to look for any configuration drift in your environment and create a new issue if changes are detected.## Workflows
1. [**Terraform Unit Tests**](.github/workflows/tf-unit-tests.yml)
This workflow runs on every commit and is composed of a set of unit tests on the infrastructure code. It runs [terraform fmt]( https://www.terraform.io/cli/commands/fmt) to ensure the code is properly linted and follows terraform best practices. Next it performs [terraform validate](https://www.terraform.io/cli/commands/validate) to check that the code is syntactically correct and internally consistent. Lastly, [checkov](https://github.com/bridgecrewio/checkov), an open source static code analysis tool for IaC, will run to detect security and compliance issues. If the repository is utilizing GitHub Advanced Security (GHAS), the results will be uploaded to GitHub.
2. [**Terraform Plan / Apply**](.github/workflows/tf-plan-apply.yml)
This workflow runs on every pull request and on each commit to the main branch. The plan stage of the workflow is used to understand the impact of the IaC changes on the Azure environment by running [terraform plan](https://www.terraform.io/cli/commands/plan). This report is then attached to the PR for easy review. The apply stage runs after the plan when the workflow is triggered by a push to the main branch. This stage will take the plan document and [apply](https://www.terraform.io/cli/commands/apply) the changes after a manual review has signed off if there are any pending changes to the environment.
3. [**Terraform Drift Detection**](.github/workflows/tf-drift.yml)
This workflow runs on a periodic basis to scan your environment for any configuration drift or changes made outside of terraform. If any drift is detected, a GitHub Issue is raised to alert the maintainers of the project.
## Getting Started
To use these workflows in your environment several prerequisite steps are required:
1. **Configure Terraform State Location**
Terraform utilizes a [state file](https://www.terraform.io/language/state) to store information about the current state of your managed infrastructure and associated configuration. This file will need to be persisted between different runs of the workflow. The recommended approach is to store this file within an Azure Storage Account or other similar remote backend. Normally, this storage would be provisioned manually or via a separate workflow. The [Terraform backend block](main.tf#L10-L16) will need updated with your selected storage location (see [here](https://developer.hashicorp.com/terraform/language/settings/backends/azurerm) for documentation).
2. **Create GitHub Environment**
The workflows utilizes GitHub Environments and Secrets to store the azure identity information and setup an approval process for deployments. Create an environment named `production` by following these [instructions](https://docs.github.com/actions/deployment/targeting-different-environments/using-environments-for-deployment#creating-an-environment). On the `production` environment setup a protection rule and add any required approvers you want that need to sign off on production deployments. You can also limit the environment to your main branch. Detailed instructions can be found [here](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#environment-protection-rules).
3. **Setup Azure Identity**:
An Azure Active Directory application is required that has permissions to deploy within your Azure subscription. Create a separate application for a `read-only` and `read/write` accounts and give them the appropriate permissions in your Azure subscription. In addition, both roles will also need at least `Reader and Data Access` permissions to the storage account where the Terraform state from step 1 resides. Next, setup the federated credentials to allow GitHub to utilize the identity using OIDC. See the [Azure documentation](https://docs.microsoft.com/azure/developer/github/connect-from-azure?tabs=azure-portal%2Clinux#use-the-azure-login-action-with-openid-connect) for detailed instructions.
For the `read/write` identity create 1 federated credential as follows:
- Set `Entity Type` to `Environment` and use the `production` environment name.For the `read-only` identity create 2 federated credentials as follows:
- Set `Entity Type` to `Pull Request`.
- Set `Entity Type` to `Branch` and use the `main` branch name.4. **Add GitHub Secrets**
_Note: While none of the data about the Azure identities contain any secrets or credentials we still utilize GitHub Secrets as a convenient means to parameterize the identity information per environment._
Create the following secrets on the repository using the `read-only` identity:
- `AZURE_CLIENT_ID` : The application (client) ID of the app registration in Azure
- `AZURE_TENANT_ID` : The tenant ID of Azure Active Directory where the app registration is defined.
- `AZURE_SUBSCRIPTION_ID` : The subscription ID where the app registration is defined.
Instructions to add the secrets to the repository can be found [here](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository).
Additionally create an additional secret on the `production` environment using the `read-write` identity:
- `AZURE_CLIENT_ID` : The application (client) ID of the app registration in AzureInstructions to add the secrets to the environment can be found [here](https://docs.github.com/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-an-environment). The environment secret will override the repository secret when doing the deploy step to the `production` environment when elevated read/write permissions are required.
## Additional ResourcesA companion article detailing how to use GitHub Actions to deploy to Azure using IaC can be found at the [DevOps Resource Center](https://learn.microsoft.com/devops/deliver/iac-github-actions).