infra #152
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: infra | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| action: | |
| description: "Terraform action" | |
| required: true | |
| type: choice | |
| default: apply | |
| options: [apply, destroy] | |
| auto_approve: | |
| description: "Apply/destroy without manual approval" | |
| required: true | |
| type: boolean | |
| default: true | |
| repository_dispatch: | |
| types: [wake] | |
| push: | |
| branches: [main] | |
| paths: | |
| - "infra/**" | |
| - "!infra/control-plane/**" | |
| - ".github/workflows/infra.yml" | |
| permissions: | |
| id-token: write | |
| contents: read | |
| env: | |
| AWS_REGION: us-east-1 | |
| TF_IN_AUTOMATION: "1" | |
| TF_LOCK_TIMEOUT: 10m | |
| ACTION: ${{ github.event_name == 'workflow_dispatch' && inputs.action || (github.event_name == 'repository_dispatch' && github.event.action == 'wake' && github.event.client_payload.action) || 'apply' }} | |
| AUTO_APPROVE: ${{ github.event_name == 'workflow_dispatch' && inputs.auto_approve || (github.event_name == 'repository_dispatch' && github.event.action == 'wake' && github.event.client_payload.auto_approve) || 'true' }} | |
| TF_VAR_hosted_zone_id: ${{ secrets.HOSTED_ZONE_ID }} | |
| TF_VAR_acm_certificate_arn: ${{ secrets.ACM_CERT_ARN }} | |
| TF_VAR_ami_id: ami-0157af9aea2eef346 | |
| concurrency: | |
| group: infra-${{ github.ref || 'refs/heads/main' }} | |
| cancel-in-progress: true | |
| jobs: | |
| terraform: | |
| if: ${{ vars.INFRA_ARMED == 'on' }} | |
| runs-on: ubuntu-latest | |
| outputs: | |
| applied: ${{ steps.set_out.outputs.applied }} | |
| defaults: | |
| run: | |
| working-directory: infra | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 | |
| with: | |
| fetch-depth: 0 | |
| - name: Mask sensitive strings | |
| run: | | |
| set -euo pipefail | |
| ROLE_ARN="${{ secrets.TF_ROLE_ARN }}" | |
| ACC="$(printf '%s' "$ROLE_ARN" | sed -n 's#^arn:aws:iam::\([0-9]\+\):.*#\1#p')" | |
| mask(){ s="${1:-}"; [ -n "$s" ] && echo "::add-mask::$s"; } | |
| mask "$ACC" | |
| mask "${GITHUB_REPOSITORY}" | |
| mask "${GITHUB_REPOSITORY%/*}" | |
| mask "${GITHUB_REPOSITORY#*/}" | |
| mask "multi-tier-demo-wait-site" | |
| mask "EVOB3TLZSKCR0" | |
| mask "e40una40of.execute-api.us-east-1.amazonaws.com" | |
| mask "https://e40una40of.execute-api.us-east-1.amazonaws.com/prod" | |
| mask "app.multi-tier.space" | |
| mask "multi-tier.space" | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@651471c36a6092792c552e8b1bef71e592b462d8 | |
| with: | |
| terraform_version: 1.9.8 | |
| terraform_wrapper: false | |
| - name: Terraform version | |
| run: terraform version | |
| - name: Configure AWS credentials (OIDC) | |
| uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 | |
| with: | |
| role-to-assume: ${{ secrets.TF_ROLE_ARN }} | |
| role-session-name: gha-terraform | |
| role-duration-seconds: 3600 | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Check required TF vars | |
| run: | | |
| set -euo pipefail | |
| for v in TF_VAR_hosted_zone_id TF_VAR_acm_certificate_arn TF_VAR_ami_id; do | |
| if [ -z "${!v:-}" ]; then | |
| echo "::error title=Missing Terraform variable::$v is not set" | |
| exit 1 | |
| fi | |
| done | |
| - name: Terraform fmt (check) | |
| run: terraform fmt -check -recursive | |
| - name: Terraform init | |
| run: terraform init -input=false -no-color | |
| - name: Terraform validate | |
| run: terraform validate -no-color | |
| - name: Terraform plan (apply) | |
| if: ${{ env.ACTION == 'apply' }} | |
| run: terraform plan -input=false -lock-timeout=${{ env.TF_LOCK_TIMEOUT }} -out=tfplan -no-color | |
| - name: Terraform apply saved plan | |
| if: ${{ env.ACTION == 'apply' && env.AUTO_APPROVE == 'true' }} | |
| run: terraform apply -input=false -auto-approve -lock-timeout=${{ env.TF_LOCK_TIMEOUT }} tfplan -no-color | |
| - name: Set output "applied" | |
| id: set_out | |
| if: ${{ env.ACTION == 'apply' }} | |
| run: echo "applied=true" >> "$GITHUB_OUTPUT" | |
| - name: Terraform plan (destroy) | |
| if: ${{ env.ACTION == 'destroy' }} | |
| run: terraform plan -destroy -input=false -lock-timeout=${{ env.TF_LOCK_TIMEOUT }} -out=tfplan -no-color | |
| - name: Terraform destroy saved plan | |
| if: ${{ env.ACTION == 'destroy' && env.AUTO_APPROVE == 'true' }} | |
| run: terraform apply -input=false -auto-approve -lock-timeout=${{ env.TF_LOCK_TIMEOUT }} tfplan -no-color | |
| - name: Arm reaper and set last_wake (after apply) | |
| if: ${{ env.ACTION == 'apply' }} | |
| run: | | |
| aws ssm put-parameter --region ${{ env.AWS_REGION }} --name /multi-tier-demo/last_wake --type String --overwrite --value $(date -u +%s) | |
| aws ssm put-parameter --region ${{ env.AWS_REGION }} --name /multi-tier-demo/reaper_armed --type String --overwrite --value on | |
| - name: Disarm reaper (after destroy) | |
| if: ${{ env.ACTION == 'destroy' }} | |
| run: | | |
| aws ssm put-parameter --region ${{ env.AWS_REGION }} --name /multi-tier-demo/reaper_armed --type String --overwrite --value off | |
| aws ssm delete-parameter --region ${{ env.AWS_REGION }} --name /multi-tier-demo/destroy_dispatched_epoch || true |