GitHub Action: atmos-terraform-drift-remediation
This Github Action is used to remediate drift
Introduction
This action is used for drift remediation.
There is another companion action github-action-atmos-terraform-drift-detection.
Usage
Config
Please note! This GitHub Action only works with atmos >= 1.99.0
.
If you are using atmos >= 1.63.0, < 1.99.0
please use v2
version of this action.
If you are using atmos < 1.63.0
please use v1
version of this action.
The action expects the atmos configuration file atmos.yaml
to be present in the repository.
The action supports AWS and Azure to store Terraform plan files.
You can read more about plan storage in the cloudposse/github-action-terraform-plan-storage documentation.
Depends of cloud provider the following fields should be set in the atmos.yaml
:
AWS
The config should have the following structure:
integrations:
github:
gitops:
opentofu-version: 1.7.3
terraform-version: 1.5.2
infracost-enabled: false
artifact-storage:
region: us-east-2
bucket: cptest-core-ue2-auto-gitops
table: cptest-core-ue2-auto-gitops-plan-storage
role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha
role:
plan: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
# Set `apply` empty if you don't want to assume IAM role before terraform apply
apply: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
matrix:
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")
Azure
The config should have the following structure:
integrations:
github:
gitops:
opentofu-version: 1.7.3
terraform-version: 1.5.2
infracost-enabled: false
artifact-storage:
plan-repository-type: azureblob
blob-account-name: tfplans
blob-container-name: plans
metadata-repository-type: cosmos
cosmos-container-name: terraform-plan-storage
cosmos-database-name: terraform-plan-storage
cosmos-endpoint: "https://my-cosmo-account.documents.azure.com:443/"
# We remove the `role` section as it is AWS specific
matrix:
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")
Stack level configuration
Wherever it is possible to specify integration.github.gitops
on stack level
it is required to define default values in atmos.yaml
It is possible to override integration settings on a stack level by defining settings.integrations
.
components:
terraform:
foobar:
settings:
integrations:
github:
gitops:
artifact-storage:
bucket: cptest-plat-ue2-auto-gitops
table: cptest-plat-ue2-auto-gitops-plan-storage
role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-plat-ue2-auto-gitops-gha
role:
# Set `plan` empty if you don't want to assume IAM role before terraform plan
plan: arn:aws:iam::yyyyyyyyyyyy:role/cptest-plat-gbl-identity-gitops
apply: arn:aws:iam::yyyyyyyyyyyy:role/cptest-plat-gbl-identity-gitops
Support OpenTofu
This action supports OpenTofu.
Please note! OpenTofu supported by Atmos >= 1.73.0
.
For details read
To enable OpenTofu add the following settings to atmos.yaml
- Set the
opentofu-version
in theatmos.yaml
to the desired version - Set
components.terraform.command
totofu
Example
components:
terraform:
command: tofu
...
integrations:
github:
gitops:
opentofu-version: 1.7.3
...
Workflow example
In this example drift will be remediated when user sets label apply
to an issue.
name: 👽 Atmos Terraform Drift Remediation
run-name: 👽 Atmos Terraform Drift Remediation
on:
issues:
types:
- labeled
- closed
permissions:
id-token: write
contents: read
jobs:
remediate-drift:
runs-on: ubuntu-latest
name: Remediate Drift
if: |
github.event.action == 'labeled' &&
contains(join(github.event.issue.labels.*.name, ','), 'apply')
steps:
- name: Remediate Drift
uses: cloudposse/github-action-atmos-terraform-drift-remediation@v1
with:
issue-number: ${{ github.event.issue.number }}
action: remediate
atmos-config-path: ./rootfs/usr/local/etc/atmos/
discard-drift:
runs-on: ubuntu-latest
name: Discard Drift
if: |
github.event.action == 'closed' &&
!contains(join(github.event.issue.labels.*.name, ','), 'remediated')
steps:
- name: Discard Drift
uses: cloudposse/github-action-atmos-terraform-drift-remediation@v1
with:
issue-number: ${{ github.event.issue.number }}
action: discard
atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml
Migrating from v2
to v3
The notable changes in v3
are:
v3
works only withatmos >= 1.99.0
v3
usecloudposse/github-action-atmos-terraform-apply@v3
v3
supports stack level integration gitops settingsv3
allow to skip internal checkout withskip-checkout
input
The only required migration step is updating atmos version to >= 1.99.0
Migrating from v1
to v2
The notable changes in v2
are:
v2
works only withatmos >= 1.63.0
v2
dropsinstall-terraform
input because terraform is not required for affected stacks callv2
dropsatmos-gitops-config-path
input and the./.github/config/atmos-gitops.yaml
config file. Now you have to use GitHub Actions environment variables to specify the location of theatmos.yaml
.
The following configuration fields now moved to GitHub action inputs with the same names
name |
---|
atmos-version |
atmos-config-path |
The following configuration fields moved to the atmos.yaml
configuration file.
name | YAML path in atmos.yaml |
---|---|
aws-region | integrations.github.gitops.artifact-storage.region |
terraform-state-bucket | integrations.github.gitops.artifact-storage.bucket |
terraform-state-table | integrations.github.gitops.artifact-storage.table |
terraform-state-role | integrations.github.gitops.artifact-storage.role |
terraform-plan-role | integrations.github.gitops.role.plan |
terraform-apply-role | integrations.github.gitops.role.apply |
terraform-version | integrations.github.gitops.terraform-version |
enable-infracost | integrations.github.gitops.infracost-enabled |
sort-by | integrations.github.gitops.matrix.sort-by |
group-by | integrations.github.gitops.matrix.group-by |
For example, to migrate from v1
to v2
, you should have something similar to the following in your atmos.yaml
:
./.github/config/atmos.yaml
# ... your existing configuration
integrations:
github:
gitops:
terraform-version: 1.5.2
infracost-enabled: false
artifact-storage:
region: us-east-2
bucket: cptest-core-ue2-auto-gitops
table: cptest-core-ue2-auto-gitops-plan-storage
role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha
role:
plan: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
apply: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
matrix:
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")
.github/workflows/main.yaml
- name: Remediate Drift
uses: cloudposse/github-action-atmos-terraform-drift-remediation@v2
with:
issue-number: ${{ github.event.issue.number }}
action: remediate
atmos-config-path: ./rootfs/usr/local/etc/atmos/
This corresponds to the v1
configuration (deprecated) below.
The v1
configuration file ./.github/config/atmos-gitops.yaml
looked like this:
atmos-version: 1.45.3
atmos-config-path: ./rootfs/usr/local/etc/atmos/
terraform-state-bucket: cptest-core-ue2-auto-gitops
terraform-state-table: cptest-core-ue2-auto-gitops
terraform-state-role: arn:aws:iam::xxxxxxxxxxxx:role/cptest-core-ue2-auto-gitops-gha
terraform-plan-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
terraform-apply-role: arn:aws:iam::yyyyyyyyyyyy:role/cptest-core-gbl-identity-gitops
terraform-version: 1.5.2
aws-region: us-east-2
enable-infracost: false
sort-by: .stack_slug
group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-")
And the v1
GitHub Action Workflow looked like this.
.github/workflows/main.yaml
- name: Remediate Drift
uses: cloudposse/github-action-atmos-terraform-drift-remediation@v1
with:
issue-number: ${{ github.event.issue.number }}
action: remediate
atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml
Migrating from v0
to v1
v2
drops thecomponent-path
variable and instead fetches if directly from theatmos.yaml
file automatically. Simply remove thecomponent-path
argument from your invocations of thecloudposse/github-action-atmos-terraform-plan
action.v2
moves most of theinputs
to the Atmos GitOps config path./.github/config/atmos-gitops.yaml
. Simply create this file, transfer your settings to it, then remove the corresponding arguments from your invocations of thecloudposse/github-action-atmos-terraform-plan
action.
name |
---|
atmos-version |
atmos-config-path |
terraform-state-bucket |
terraform-state-table |
terraform-state-role |
terraform-plan-role |
terraform-apply-role |
terraform-version |
aws-region |
enable-infracost |
If you want the same behavior in v1
as inv0
you should create config ./.github/config/atmos-gitops.yaml
with the same variables as in v0
inputs.
- name: Remediate Drift
uses: cloudposse/github-action-atmos-terraform-drift-remediation@v1
with:
issue-number: ${{ github.event.issue.number }}
action: remediate
atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml
Which would produce the same behavior as in v0
, doing this:
- name: Remediate Drift
uses: cloudposse/github-action-atmos-terraform-drift-remediation@v0
with:
issue-number: ${{ github.event.issue.number }}
action: remediate
atmos-config-path: "${{ github.workspace }}/rootfs/usr/local/etc/atmos/"
terraform-plan-role: "arn:aws:iam::111111111111:role/acme-core-gbl-identity-gitops"
terraform-state-bucket: "acme-core-ue2-auto-gitops"
terraform-state-role: "arn:aws:iam::999999999999:role/acme-core-ue2-auto-gitops-gha"
terraform-state-table: "acme-core-ue2-auto-gitops"
aws-region: "us-east-2"
Inputs
Name | Description | Default | Required |
---|---|---|---|
action | Drift remediation action. One of ['remediate', 'discard'] | remediate | false |
atmos-config-path | The path to the atmos.yaml file | N/A | true |
atmos-version | The version of atmos to install | >= 1.99.0 | false |
debug | Enable action debug mode. Default: 'false' | false | false |
issue-number | Issue Number | N/A | true |
skip-checkout | Disable actions/checkout. Useful for when the checkout happens in a previous step and file are modified outside of git through other actions | false | false |
token | Used to pull node distributions for Atmos from Cloud Posse's GitHub repository. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting. | ${{ github.server_url == 'https://github.com' && github.token || '' }} | false |