diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 0df932f..74a7890 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -19,28 +19,29 @@ jobs: setup: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + - shell: bash run: | mkdir -p ${{ runner.temp }} - cat > ${{ runner.temp }}/atmos-gitops.yaml < ${{ runner.temp }}/atmos-gitops.yaml < -# github-action-atmos-terraform-apply - - [![Latest Release](https://img.shields.io/github/release/cloudposse/github-action-atmos-terraform-apply.svg)](https://github.com/cloudposse/github-action-atmos-terraform-apply/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) +# github-action-atmos-terraform-apply +Latest ReleaseSlack Community - - [logo]: https://cloudposse.com/logo-300x69.svg - [docs]: https://cpco.io/docs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=docs - [website]: https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=website - [github]: https://cpco.io/github?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=github - [jobs]: https://cpco.io/jobs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=jobs - [hire]: https://cpco.io/hire?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=hire - [slack]: https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=slack - [twitter]: https://cpco.io/twitter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=twitter - [office_hours]: https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=office_hours - [newsletter]: https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=newsletter - [email]: https://cpco.io/email?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=email - [commercial_support]: https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=commercial_support - [we_love_open_source]: https://cpco.io/we-love-open-source?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=we_love_open_source - [terraform_modules]: https://cpco.io/terraform-modules?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=terraform_modules - [readme_header_img]: https://cloudposse.com/readme/header/img - [readme_header_link]: https://cloudposse.com/readme/header/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=readme_header_link - [readme_footer_img]: https://cloudposse.com/readme/footer/img - [readme_footer_link]: https://cloudposse.com/readme/footer/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=readme_footer_link - [readme_commercial_support_img]: https://cloudposse.com/readme/commercial-support/img - [readme_commercial_support_link]: https://cloudposse.com/readme/commercial-support/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/github-action-atmos-terraform-apply&utm_content=readme_commercial_support_link - [beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/github-action-atmos-terraform-apply?pixel&cs=github&cm=readme&an=github-action-atmos-terraform-apply - +Copyright Β© 2017-2024 [Cloud Posse, LLC](https://cpco.io/copyright) + + +README footer + +Beacon diff --git a/README.yaml b/README.yaml index d6d6fde..c7d0034 100644 --- a/README.yaml +++ b/README.yaml @@ -60,24 +60,31 @@ usage: |- ### Config - The action expects the atmos gitops configuration file to be present in the repository in `./.github/config/atmos-gitops.yaml`. + The action expects the atmos configuration file `atmos.yaml` to be present in the repository. The config should have the following structure: ```yaml - 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("-") + 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("-") ``` + > [!IMPORTANT] + > **Please note!** This GitHub Action only works with `atmos >= 1.63.0`. If you are using `atmos < 1.63.0` please use `v1` version of this action. + ### Workflow example In this example, the action is triggered when certain events occur, such as a manual workflow dispatch or the opening, synchronization, or reopening of a pull request, specifically on the main branch. It specifies specific permissions related to assuming roles in AWS. Within the "apply" job, the "component" and "stack" are hardcoded (`foobar` and `plat-ue2-sandbox`). In practice, these are usually derived from another action. @@ -110,12 +117,111 @@ usage: |- with: component: "foobar" stack: "plat-ue2-sandbox" + atmos-config-path: ./rootfs/usr/local/etc/atmos/ ``` ### Migrating from `v1` to `v2` - 1. `v2` drops the `component-path` variable and instead fetches if directly from the [`atmos.yaml` file](https://atmos.tools/cli/configuration/) automatically. Simply remove the `component-path` argument from your invocations of the `cloudposse/github-action-atmos-terraform-apply` action. - 2. `v2` moves most of the `inputs` 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 the `cloudposse/github-action-atmos-terraform-apply` action. + The notable changes in `v2` are: + + - `v2` works only with `atmos >= 1.63.0` + - `v2` drops `install-terraform` input because terraform is not required for affected stacks call + - `v2` drops `atmos-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 the `atmos.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` + ```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` + ```yaml + - name: Plan Atmos Component + uses: cloudposse/github-action-atmos-terraform-apply@v2 + with: + component: "foobar" + stack: "plat-ue2-sandbox" + atmos-config-path: ./rootfs/usr/local/etc/atmos/ + atmos-version: 1.63.0 + ``` + + This corresponds to the `v1` configuration (deprecated) below. + + The `v1` configuration file `./.github/config/atmos-gitops.yaml` looked like this: + + ```yaml + 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` + ```yaml + - name: Plan Atmos Component + uses: cloudposse/github-action-atmos-terraform-apply@v1 + with: + component: "foobar" + stack: "plat-ue2-sandbox" + atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml + ``` + + ### Migrating from `v0` to `v1` + + 1. `v1` drops the `component-path` variable and instead fetches if directly from the [`atmos.yaml` file](https://atmos.tools/cli/configuration/) automatically. Simply remove the `component-path` argument from your invocations of the `cloudposse/github-action-atmos-terraform-apply` action. + 2. `v1` moves most of the `inputs` 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 the `cloudposse/github-action-atmos-terraform-apply` action. | name | |--------------------------| @@ -131,22 +237,22 @@ usage: |- | `enable-infracost` | - If you want the same behavior in `v2` as in `v1` you should create config `./.github/config/atmos-gitops.yaml` with the same variables as in `v1` inputs. + If you want the same behavior in `v1` as in `v0` you should create config `./.github/config/atmos-gitops.yaml` with the same variables as in `v0` inputs. ```yaml - name: Terraform apply - uses: cloudposse/github-action-atmos-terraform-apply@v2 + uses: cloudposse/github-action-atmos-terraform-apply@v1 with: atmos-gitops-config-path: ./.github/config/atmos-gitops.yaml component: "foobar" stack: "plat-ue2-sandbox" ``` - Which would produce the same behavior as in `v1`, doing this: + Which would produce the same behavior as in `v0`, doing this: ```yaml - name: Terraform apply - uses: cloudposse/github-action-atmos-terraform-apply@v1 + uses: cloudposse/github-action-atmos-terraform-apply@v0 with: component: "foobar" stack: "plat-ue2-sandbox" diff --git a/action.yml b/action.yml index cc3159d..f3afd3b 100644 --- a/action.yml +++ b/action.yml @@ -15,10 +15,13 @@ inputs: description: "Commit SHA to apply. Default: github.sha" required: true default: "${{ github.event.pull_request.head.sha }}" - atmos-gitops-config-path: - description: The path to the atmos-gitops.yaml file + atmos-version: + description: The version of atmos to install required: false - default: ./.github/config/atmos-gitops.yaml + default: ">= 1.63.0" + atmos-config-path: + description: The path to the atmos.yaml file + required: true infracost-api-key: description: "Infracost API key" required: false @@ -51,20 +54,30 @@ runs: - name: Checkout uses: actions/checkout@v4 - - name: Read Atmos GitOps config - ## We have to reference cloudposse fork of https://github.com/blablacar/action-config-levels - ## before https://github.com/blablacar/action-config-levels/pull/16 would be merged - uses: cloudposse/github-action-config-levels@nodejs20 - id: config + - name: Set atmos cli config path vars + shell: bash + run: |- + echo "ATMOS_CLI_CONFIG_PATH=$(realpath ${{ inputs.atmos-config-path }})" >> $GITHUB_ENV + + - name: Install Atmos + uses: cloudposse/github-action-setup-atmos@v2 with: - output_properties: true - patterns: | - - ${{ inputs.atmos-gitops-config-path }} + atmos-version: ${{ inputs.atmos-version }} + token: ${{ inputs.token }} + install-wrapper: false - - name: Set atmos cli config path vars + - name: config shell: bash + id: config run: |- - echo "ATMOS_CLI_CONFIG_PATH=$(realpath ${{ steps.config.outputs.atmos-config-path }})" >> $GITHUB_ENV + echo "terraform-version=$(atmos describe config -f json | jq -r '.integrations.github.gitops["terraform-version"]')" >> $GITHUB_OUTPUT + echo "enable-infracost=$(atmos describe config -f json | jq -r '.integrations.github.gitops["infracost-enabled"]')" >> $GITHUB_OUTPUT + echo "aws-region=$(atmos describe config -f json | jq -r '.integrations.github.gitops["artifact-storage"].region')" >> $GITHUB_OUTPUT + echo "terraform-state-role=$(atmos describe config -f json | jq -r '.integrations.github.gitops["artifact-storage"].role')" >> $GITHUB_OUTPUT + echo "terraform-state-table=$(atmos describe config -f json | jq -r '.integrations.github.gitops["artifact-storage"].table')" >> $GITHUB_OUTPUT + echo "terraform-state-bucket=$(atmos describe config -f json | jq -r '.integrations.github.gitops["artifact-storage"].bucket')" >> $GITHUB_OUTPUT + echo "terraform-plan-role=$(atmos describe config -f json | jq -r '.integrations.github.gitops.role.plan')" >> $GITHUB_OUTPUT + echo "terraform-apply-role=$(atmos describe config -f json | jq -r '.integrations.github.gitops.role.apply')" >> $GITHUB_OUTPUT - name: Install Terraform uses: hashicorp/setup-terraform@v3 @@ -77,14 +90,6 @@ runs: with: node-version: 20 - - - name: Install Atmos - uses: cloudposse/github-action-setup-atmos@v2 - with: - atmos-version: ${{ steps.config.outputs.atmos-version }} - token: ${{ inputs.token }} - install-wrapper: false - - name: Filter Atmos Settings Value uses: cloudposse/github-action-atmos-get-setting@v1 id: atmos-github-actions-enabled @@ -134,7 +139,7 @@ runs: # Set ATMOS_BASE_PATH allow `cloudposse/utils` provider to read atmos config from the correct path ATMOS_BASE_PATH="${{ steps.base-path.outputs.value }}" echo "ATMOS_BASE_PATH=$(realpath ${ATMOS_BASE_PATH:-./})" >> $GITHUB_ENV - + - name: Install tfcmt if: env.ACTIONS_ENABLED == 'true' uses: jaxxstorm/action-install-gh-release@v1.11.0 @@ -213,13 +218,6 @@ runs: role-session-name: "atmos-terraform-apply-gitops" mask-aws-account-id: "no" - - name: Atmos Setup Workspace - if: env.ACTIONS_ENABLED == 'true' - id: atmos-init - shell: bash - run: | - atmos terraform workspace ${{ inputs.component }} -s ${{ inputs.stack }} - - name: Check Whether Infracost is Enabled if: env.ACTIONS_ENABLED == 'true' shell: bash @@ -308,10 +306,10 @@ runs: TERRAFORM_RESULT=$? set -e - + cat "${TERRAFORM_OUTPUT_FILE}" - terraform output --json > output_values.json + # terraform output --json > output_values.json # terraform-docs -c ${{ github.action_path }}/config/tfdocs-config.yaml --output-file ${{ github.workspace }}/atmos-apply-summary.md ./ @@ -319,10 +317,10 @@ runs: # sed -i "s#\`\"#\`#g" ${{ github.workspace }}/atmos-apply-summary.md # sed -i "s#\"\`#\`#g" ${{ github.workspace }}/atmos-apply-summary.md # sed -i "s#|--#|:-#g" ${{ github.workspace }}/atmos-apply-summary.md - + cat "${{ github.workspace }}/atmos-apply-summary.md" >> $GITHUB_STEP_SUMMARY - - if [ $TERRAFORM_RESULT -eq 0 ]; then + + if [[ "${TERRAFORM_RESULT}" == "0" ]]; then echo "status=succeeded" >> $GITHUB_OUTPUT echo "Terraform apply executed successfully" else diff --git a/docs/github-action.md b/docs/github-action.md index 171bbac..c1410b3 100644 --- a/docs/github-action.md +++ b/docs/github-action.md @@ -4,7 +4,8 @@ | Name | Description | Default | Required | |------|-------------|---------|----------| -| atmos-gitops-config-path | The path to the atmos-gitops.yaml file | ./.github/config/atmos-gitops.yaml | false | +| atmos-config-path | The path to the atmos.yaml file | N/A | true | +| atmos-version | The version of atmos to install | >= 1.63.0 | false | | branding-logo-image | Branding logo image url | https://cloudposse.com/logo-300x69.svg | false | | branding-logo-url | Branding logo url | https://cloudposse.com/ | false | | component | The name of the component to apply. | N/A | true | diff --git a/tests/atmos.yaml b/tests/atmos.yaml index 8ee70cf..45fa5de 100644 --- a/tests/atmos.yaml +++ b/tests/atmos.yaml @@ -59,6 +59,23 @@ stacks: # Can also be set using `ATMOS_STACKS_NAME_PATTERN` ENV var name_pattern: "{tenant}-{environment}-{stage}" +integrations: + github: + gitops: + terraform-version: 1.5.2 + infracost-enabled: __INFRACOST_ENABLED__ + artifact-storage: + region: __STORAGE_REGION__ + bucket: __STORAGE_BUCKET__ + table: __STORAGE_TABLE__ + role: __STORAGE_ROLE__ + role: + plan: __PLAN_ROLE__ + apply: __APPLY_ROLE__ + matrix: + sort-by: .stack_slug + group-by: .stack_slug | split("-") | [.[0], .[2]] | join("-") + workflows: # Can also be set using `ATMOS_WORKFLOWS_BASE_PATH` ENV var, or `--workflows-dir` command-line arguments # Supports both absolute and relative paths