From 6b597b980c094f8ff51439e3607149ae9a271ec9 Mon Sep 17 00:00:00 2001 From: "T.J. Corrigan" Date: Tue, 1 Nov 2022 10:49:10 -0500 Subject: [PATCH 1/4] Initial Version --- .github/ISSUE_TEMPLATE.md | 33 ------ .github/PULL_REQUEST_TEMPLATE.md | 45 ------- .github/dependabot.yml | 11 ++ .github/workflows/tf-drift.yml | 174 ++++++++++++++++++++++++++++ .github/workflows/tf-plan-apply.yml | 146 +++++++++++++++++++++++ .github/workflows/tf-unit-tests.yml | 45 +++++++ CHANGELOG.md | 15 +-- CONTRIBUTING.md | 6 +- README.md | 88 ++++++++------ main.tf | 28 +++++ terraform.tfvars | 3 + variables.tf | 2 + 12 files changed, 469 insertions(+), 127 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/tf-drift.yml create mode 100644 .github/workflows/tf-plan-apply.yml create mode 100644 .github/workflows/tf-unit-tests.yml create mode 100644 main.tf create mode 100644 terraform.tfvars create mode 100644 variables.tf diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 15c7f60..0000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,33 +0,0 @@ - -> Please provide us with the following information: -> --------------------------------------------------------------- - -### This issue is for a: (mark with an `x`) -``` -- [ ] bug report -> please search issues before submitting -- [ ] feature request -- [ ] documentation issue or request -- [ ] regression (a behavior that used to work and stopped in a new release) -``` - -### Minimal steps to reproduce -> - -### Any log messages given by the failure -> - -### Expected/desired behavior -> - -### OS and Version? -> Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?) - -### Versions -> - -### Mention any other details that might be useful - -> --------------------------------------------------------------- -> Thanks! We'll be in touch soon. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index ab05e29..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,45 +0,0 @@ -## Purpose - -* ... - -## Does this introduce a breaking change? - -``` -[ ] Yes -[ ] No -``` - -## Pull Request Type -What kind of change does this Pull Request introduce? - - -``` -[ ] Bugfix -[ ] Feature -[ ] Code style update (formatting, local variables) -[ ] Refactoring (no functional changes, no api changes) -[ ] Documentation content changes -[ ] Other... Please describe: -``` - -## How to Test -* Get the code - -``` -git clone [repo-address] -cd [repo-name] -git checkout [branch-name] -npm install -``` - -* Test the code - -``` -``` - -## What to Check -Verify that the following are valid -* ... - -## Other Information - \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..7602182 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "terraform" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/tf-drift.yml b/.github/workflows/tf-drift.yml new file mode 100644 index 0000000..a92b2d3 --- /dev/null +++ b/.github/workflows/tf-drift.yml @@ -0,0 +1,174 @@ +name: 'Terraform Configuration Drift Detection' + +on: + workflow_dispatch: + schedule: + - cron: '41 3 * * *' # runs nightly at 3:41 am + +#Special permissions required for OIDC authentication +permissions: + id-token: write + contents: read + issues: write + +#These environment variables are used by the terraform azure provider to setup OIDD authenticate. +env: + ARM_CLIENT_ID: "${{ secrets.AZURE_CLIENT_ID }}" + ARM_SUBSCRIPTION_ID: "${{ secrets.AZURE_SUBSCRIPTION_ID }}" + ARM_TENANT_ID: "${{ secrets.AZURE_TENANT_ID }}" + +jobs: + terraform-plan: + name: 'Terraform Plan' + runs-on: ubuntu-latest + env: + #this is needed since we are running terraform with read-only permissions + ARM_SKIP_PROVIDER_REGISTRATION: true + outputs: + tfplanExitCode: ${{ steps.tf-plan.outputs.exitcode }} + + steps: + # Checkout the repository to the GitHub Actions runner + - name: Checkout + uses: actions/checkout@v3 + + # Install the latest version of the Terraform CLI + - name: Setup Terraform + uses: hashicorp/setup-terraform@v2 + with: + terraform_wrapper: false + + # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc. + - name: Terraform Init + run: terraform init + + # Generates an execution plan for Terraform + # An exit code of 0 indicated no changes, 1 a terraform failure, 2 there are pending changes. + - name: Terraform Plan + id: tf-plan + run: | + export exitcode=0 + terraform plan -detailed-exitcode -no-color -out tfplan || export exitcode=$? + + echo "exitcode=$exitcode" >> $GITHUB_OUTPUT + + if [ $exitcode -eq 1 ]; then + echo Terraform Plan Failed! + exit 1 + else + exit 0 + fi + + # Save plan to artifacts + - name: Publish Terraform Plan + uses: actions/upload-artifact@v3 + with: + name: tfplan + path: tfplan + + # Create string output of Terraform Plan + - name: Create String Output + id: tf-plan-string + run: | + TERRAFORM_PLAN=$(terraform show -no-color tfplan) + + delimiter="$(openssl rand -hex 8)" + echo "summary<<${delimiter}" >> $GITHUB_OUTPUT + echo "## Terraform Plan Output" >> $GITHUB_OUTPUT + echo "
Click to expand" >> $GITHUB_OUTPUT + echo "" >> $GITHUB_OUTPUT + echo '```terraform' >> $GITHUB_OUTPUT + echo "$TERRAFORM_PLAN" >> $GITHUB_OUTPUT + echo '```' >> $GITHUB_OUTPUT + echo "
" >> $GITHUB_OUTPUT + echo "${delimiter}" >> $GITHUB_OUTPUT + + # Publish Terraform Plan as task summary + - name: Publish Terraform Plan to Task Summary + env: + SUMMARY: ${{ steps.tf-plan-string.outputs.summary }} + run: | + echo "$SUMMARY" >> $GITHUB_STEP_SUMMARY + + # If changes are detected, create a new issue + - name: Publish Drift Report + if: steps.tf-plan.outputs.exitcode == 2 + uses: actions/github-script@v6 + env: + SUMMARY: "${{ steps.tf-plan-string.outputs.summary }}" + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const body = `${process.env.SUMMARY}`; + const title = 'Terraform Configuration Drift Detected'; + const creator = 'github-actions[bot]' + + // Look to see if there is an existing drift issue + const issues = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + creator: creator, + title: title + }) + + if( issues.data.length > 0 ) { + // We assume there shouldn't be more than 1 open issue, since we update any issue we find + const issue = issues.data[0] + + if ( issue.body == body ) { + console.log('Drift Detected: Found matching issue with duplicate content') + } else { + console.log('Drift Detected: Found matching issue, updating body') + github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body: body + }) + } + } else { + console.log('Drift Detected: Creating new issue') + + github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: title, + body: body + }) + } + + # If changes aren't detected, close any open drift issues + - name: Publish Drift Report + if: steps.tf-plan.outputs.exitcode == 0 + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const title = 'Terraform Configuration Drift Detected'; + const creator = 'github-actions[bot]' + + // Look to see if there is an existing drift issue + const issues = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + creator: creator, + title: title + }) + + if( issues.data.length > 0 ) { + const issue = issues.data[0] + + github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + state: 'closed' + }) + } + + # Mark the workflow as failed if drift detected + - name: Error on Failure + if: steps.tf-plan.outputs.exitcode == 2 + run: exit 1 diff --git a/.github/workflows/tf-plan-apply.yml b/.github/workflows/tf-plan-apply.yml new file mode 100644 index 0000000..1e97900 --- /dev/null +++ b/.github/workflows/tf-plan-apply.yml @@ -0,0 +1,146 @@ +name: 'Terraform Plan/Apply' + +on: + push: + branches: + - main + pull_request: + branches: + - main + +#Special permissions required for OIDC authentication +permissions: + id-token: write + contents: read + pull-requests: write + +#These environment variables are used by the terraform azure provider to setup OIDD authenticate. +env: + ARM_CLIENT_ID: "${{ secrets.AZURE_CLIENT_ID }}" + ARM_SUBSCRIPTION_ID: "${{ secrets.AZURE_SUBSCRIPTION_ID }}" + ARM_TENANT_ID: "${{ secrets.AZURE_TENANT_ID }}" + +jobs: + terraform-plan: + name: 'Terraform Plan' + runs-on: ubuntu-latest + env: + #this is needed since we are running terraform with read-only permissions + ARM_SKIP_PROVIDER_REGISTRATION: true + outputs: + tfplanExitCode: ${{ steps.tf-plan.outputs.exitcode }} + + steps: + # Checkout the repository to the GitHub Actions runner + - name: Checkout + uses: actions/checkout@v3 + + # Install the latest version of the Terraform CLI + - name: Setup Terraform + uses: hashicorp/setup-terraform@v2 + with: + terraform_wrapper: false + + # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc. + - name: Terraform Init + run: terraform init + + # Checks that all Terraform configuration files adhere to a canonical format + # Will fail the build if not + - name: Terraform Format + run: terraform fmt -check + + # Generates an execution plan for Terraform + # An exit code of 0 indicated no changes, 1 a terraform failure, 2 there are pending changes. + - name: Terraform Plan + id: tf-plan + run: | + export exitcode=0 + terraform plan -detailed-exitcode -no-color -out tfplan || export exitcode=$? + + echo "exitcode=$exitcode" >> $GITHUB_OUTPUT + + if [ $exitcode -eq 1 ]; then + echo Terraform Plan Failed! + exit 1 + else + exit 0 + fi + + # Save plan to artifacts + - name: Publish Terraform Plan + uses: actions/upload-artifact@v3 + with: + name: tfplan + path: tfplan + + # Create string output of Terraform Plan + - name: Create String Output + id: tf-plan-string + run: | + TERRAFORM_PLAN=$(terraform show -no-color tfplan) + + delimiter="$(openssl rand -hex 8)" + echo "summary<<${delimiter}" >> $GITHUB_OUTPUT + echo "## Terraform Plan Output" >> $GITHUB_OUTPUT + echo "
Click to expand" >> $GITHUB_OUTPUT + echo "" >> $GITHUB_OUTPUT + echo '```terraform' >> $GITHUB_OUTPUT + echo "$TERRAFORM_PLAN" >> $GITHUB_OUTPUT + echo '```' >> $GITHUB_OUTPUT + echo "
" >> $GITHUB_OUTPUT + echo "${delimiter}" >> $GITHUB_OUTPUT + + # Publish Terraform Plan as task summary + - name: Publish Terraform Plan to Task Summary + env: + SUMMARY: ${{ steps.tf-plan-string.outputs.summary }} + run: | + echo "$SUMMARY" >> $GITHUB_STEP_SUMMARY + + # If this is a PR post the changes + - name: Push Terraform Output to PR + if: github.ref != 'refs/heads/main' + uses: actions/github-script@v6 + env: + SUMMARY: "${{ steps.tf-plan-string.outputs.summary }}" + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const body = `${process.env.SUMMARY}`; + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: body + }) + + terraform-apply: + name: 'Terraform Apply' + if: github.ref == 'refs/heads/main' && needs.terraform-plan.outputs.tfplanExitCode == 2 + runs-on: ubuntu-latest + environment: production + needs: [terraform-plan] + + steps: + # Checkout the repository to the GitHub Actions runner + - name: Checkout + uses: actions/checkout@v3 + + # Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token + - name: Setup Terraform + uses: hashicorp/setup-terraform@v2 + + # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc. + - name: Terraform Init + run: terraform init + + # Download saved plan from artifacts + - name: Download Terraform Plan + uses: actions/download-artifact@v3 + with: + name: tfplan + + # Terraform Apply + - name: Terraform Apply + run: terraform apply -auto-approve tfplan diff --git a/.github/workflows/tf-unit-tests.yml b/.github/workflows/tf-unit-tests.yml new file mode 100644 index 0000000..6ed4605 --- /dev/null +++ b/.github/workflows/tf-unit-tests.yml @@ -0,0 +1,45 @@ +name: 'Terraform Unit Tests' + +on: + push: + +jobs: + terraform-unit-tests: + name: 'Terraform Unit Tests' + runs-on: ubuntu-latest + + steps: + # Checkout the repository to the GitHub Actions runner + - name: Checkout + uses: actions/checkout@v3 + + # Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token + - name: Setup Terraform + uses: hashicorp/setup-terraform@v2 + + # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc. + - name: Terraform Init + run: terraform init -backend=false + + # Validate terraform files + - name: Terraform Validate + run: terraform validate + + # Checks that all Terraform configuration files adhere to a canonical format + - name: Terraform Format + run: terraform fmt -check -recursive + + # Perform a security scan of the terraform code using checkov + - name: Run Checkov action + id: checkov + uses: bridgecrewio/checkov-action@master + with: + framework: terraform + + # Upload results to GitHub Advanced Security + - name: Upload SARIF file + if: success() || failure() + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: results.sarif + category: checkov diff --git a/CHANGELOG.md b/CHANGELOG.md index 9824752..cc22442 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,6 @@ -## [project-title] Changelog +## GitHub Actions Workflows for Terraform Changelog - -# x.y.z (yyyy-mm-dd) + +# 1.0.0 (2022-11-01) -*Features* -* ... - -*Bug Fixes* -* ... - -*Breaking Changes* -* ... +Initial Version diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a9115cf..2935048 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to [project-title] +# Contributing to terraform-github-actions This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us @@ -51,12 +51,12 @@ chances of your issue being dealt with quickly: * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be causing the problem (line of code or commit) -You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new]. +You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/Azure-Samples/terraform-github-actions/issues/new. ### Submitting a Pull Request (PR) Before you submit your Pull Request (PR) consider the following guidelines: -* Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR +* Search the repository (https://github.com/Azure-Samples/terraform-github-actions/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate effort. * Make your changes in a new git fork: diff --git a/README.md b/README.md index 364f052..62dade7 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,75 @@ -# Project Name +# GitHub Actions Workflows for Terraform -(short, 1-3 sentenced, description of the project) +This is a sample repository that shows how to use GitHub Actions workflows to manage Azure infrastructure with Terraform. -## Features +## Architecture -This project framework provides the following features: +GitHub Actions CICD for Terraform -* Feature 1 -* Feature 2 -* ... +## Dataflow -## Getting Started +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 complaince issues. If the repository is utilizing GitHub Advanced Security (GHAS), the results will be uploaded to GitHub. -### Prerequisites +2. [**Terraform Plan / Apply**](.github/workflows/tf-plan-apply.yml) -(ideally very short, if any) + 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. -- OS -- Library version -- ... +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 -### Installation +To use these workflows in your environment several prerequisite steps are required: -(ideally very short) +1. **Configure Terraform State Location** -- npm install [package name] -- mvn install -- ... + 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). -### Quickstart -(Add steps to get up and running quickly) +2. **Create GitHub Environment** -1. git clone [repository clone url] -2. cd [repository name] -3. ... + 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 [insturctions](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**: -## Demo + 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. -A demo app is included to show how to use the project. + 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. -To run the demo, follow these steps: +4. **Add GitHub Secrets** -(Add steps to start up the demo) + _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._ -1. -2. -3. + Create the following secrets on the repository using the `read-only` identity: -## Resources + - `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 Azure -(Any additional resources or related projects) + Instructions 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 Resources -- Link to supporting information -- Link to similar sample -- ... +A companion article detailing how to use GitHub Actions to deploy to Azure using IaC can be found at the [DevOps Resource Center](). `TODO: add link` diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..22ae8df --- /dev/null +++ b/main.tf @@ -0,0 +1,28 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 3.7.0" + } + } + + # Update this block with the location of your terraform state file + backend "azurerm" { + resource_group_name = "rg-terraform-github-actions-state" + storage_account_name = "terraformgithubactions" + container_name = "tfstate" + key = "terraform.tfstate" + use_oidc = true + } +} + +provider "azurerm" { + features {} + use_oidc = true +} + +# Define any Azure resources to be created here. A simple resource group is shown here as a minimal example. +resource "azurerm_resource_group" "rg-aks" { + name = var.resource_group_name + location = var.location +} diff --git a/terraform.tfvars b/terraform.tfvars new file mode 100644 index 0000000..6440d63 --- /dev/null +++ b/terraform.tfvars @@ -0,0 +1,3 @@ +# Sample values +resource_group_name = "rg-terraform-github-actions" +location = "eastus" diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..6b68db1 --- /dev/null +++ b/variables.tf @@ -0,0 +1,2 @@ +variable "resource_group_name" {} +variable "location" {} From 56ba79ef8ee7b0ee29da1c9bb250a5247d4b4208 Mon Sep 17 00:00:00 2001 From: "T.J. Corrigan" Date: Tue, 1 Nov 2022 10:57:54 -0500 Subject: [PATCH 2/4] README typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 62dade7..7ce963b 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ This is a sample repository that shows how to use GitHub Actions workflows to ma 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 complaince issues. If the repository is utilizing GitHub Advanced Security (GHAS), the results will be uploaded to GitHub. + 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) From 2a0f34f27ce9c9f3a16575ec61b772878f75e38e Mon Sep 17 00:00:00 2001 From: Tugdual Grall Date: Thu, 19 Oct 2023 07:55:46 -1000 Subject: [PATCH 3/4] Update README.md (#3) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ce963b..12e0ccf 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ To use these workflows in your environment several prerequisite steps are requir 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 [insturctions](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). + 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**: From f4eb48d54c236e076851053dc2c43d391e61d290 Mon Sep 17 00:00:00 2001 From: "T.J. Corrigan" Date: Thu, 28 Mar 2024 08:08:25 -0500 Subject: [PATCH 4/4] Update GitHub Actions workflows to use node20 (#24) --- .github/workflows/tf-drift.yml | 10 +++++----- .github/workflows/tf-plan-apply.yml | 14 +++++++------- .github/workflows/tf-unit-tests.yml | 11 ++++++++--- README.md | 2 +- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/.github/workflows/tf-drift.yml b/.github/workflows/tf-drift.yml index a92b2d3..200b900 100644 --- a/.github/workflows/tf-drift.yml +++ b/.github/workflows/tf-drift.yml @@ -30,11 +30,11 @@ jobs: steps: # Checkout the repository to the GitHub Actions runner - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Install the latest version of the Terraform CLI - name: Setup Terraform - uses: hashicorp/setup-terraform@v2 + uses: hashicorp/setup-terraform@v3 with: terraform_wrapper: false @@ -61,7 +61,7 @@ jobs: # Save plan to artifacts - name: Publish Terraform Plan - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: tfplan path: tfplan @@ -93,7 +93,7 @@ jobs: # If changes are detected, create a new issue - name: Publish Drift Report if: steps.tf-plan.outputs.exitcode == 2 - uses: actions/github-script@v6 + uses: actions/github-script@v7 env: SUMMARY: "${{ steps.tf-plan-string.outputs.summary }}" with: @@ -141,7 +141,7 @@ jobs: # If changes aren't detected, close any open drift issues - name: Publish Drift Report if: steps.tf-plan.outputs.exitcode == 0 - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/tf-plan-apply.yml b/.github/workflows/tf-plan-apply.yml index 1e97900..d0a9b83 100644 --- a/.github/workflows/tf-plan-apply.yml +++ b/.github/workflows/tf-plan-apply.yml @@ -33,11 +33,11 @@ jobs: steps: # Checkout the repository to the GitHub Actions runner - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Install the latest version of the Terraform CLI - name: Setup Terraform - uses: hashicorp/setup-terraform@v2 + uses: hashicorp/setup-terraform@v3 with: terraform_wrapper: false @@ -69,7 +69,7 @@ jobs: # Save plan to artifacts - name: Publish Terraform Plan - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: tfplan path: tfplan @@ -101,7 +101,7 @@ jobs: # If this is a PR post the changes - name: Push Terraform Output to PR if: github.ref != 'refs/heads/main' - uses: actions/github-script@v6 + uses: actions/github-script@v7 env: SUMMARY: "${{ steps.tf-plan-string.outputs.summary }}" with: @@ -125,11 +125,11 @@ jobs: steps: # Checkout the repository to the GitHub Actions runner - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token - name: Setup Terraform - uses: hashicorp/setup-terraform@v2 + uses: hashicorp/setup-terraform@v3 # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc. - name: Terraform Init @@ -137,7 +137,7 @@ jobs: # Download saved plan from artifacts - name: Download Terraform Plan - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: tfplan diff --git a/.github/workflows/tf-unit-tests.yml b/.github/workflows/tf-unit-tests.yml index 6ed4605..67bfdd4 100644 --- a/.github/workflows/tf-unit-tests.yml +++ b/.github/workflows/tf-unit-tests.yml @@ -3,6 +3,11 @@ name: 'Terraform Unit Tests' on: push: +permissions: + security-events: write # Needed to upload-sarif + contents: read # Needed to clone repo + actions: read # Potentially needed for private repositories (see https://github.com/github/codeql-action/issues/2117) + jobs: terraform-unit-tests: name: 'Terraform Unit Tests' @@ -11,11 +16,11 @@ jobs: steps: # Checkout the repository to the GitHub Actions runner - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token - name: Setup Terraform - uses: hashicorp/setup-terraform@v2 + uses: hashicorp/setup-terraform@v3 # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc. - name: Terraform Init @@ -39,7 +44,7 @@ jobs: # Upload results to GitHub Advanced Security - name: Upload SARIF file if: success() || failure() - uses: github/codeql-action/upload-sarif@v2 + uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif category: checkov diff --git a/README.md b/README.md index 12e0ccf..e25e6ac 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ To use these workflows in your environment several prerequisite steps are requir ## Additional Resources -A companion article detailing how to use GitHub Actions to deploy to Azure using IaC can be found at the [DevOps Resource Center](). `TODO: add link` +A 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).