Decouple environment approvals from deploy_order; add make smoke#35
Merged
Conversation
…ract Closes #34 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
State
|
| Success | 🟢 Add | 🟡 Change | Destroy |
|---|---|---|---|
| ✅ | 1 | 5 | 0 |
Affected resources by action
| Action | Resources |
|---|---|
| 🟢 | module.aws_service_infrahouse_app.github_repository_environment.cd["production"] |
| 🟡 | github_team_members.admins |
| 🟡 | github_team_members.dev |
| 🟡 | module.aws_service_infrahouse_app.github_repository_environment.cd["sandbox"] |
| 🟡 | module.aws_service_infrahouse_app.github_repository_file.makefile_fragment[0] |
| 🟡 | module.aws_service_infrahouse_app.github_repository_file.terraform_cd[0] |
STDOUT
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
~ update in-place
Terraform will perform the following actions:
# github_team_members.admins will be updated in-place
~ resource "github_team_members" "admins" {
id = "14268696"
# (1 unchanged attribute hidden)
- members {
- role = "maintainer" -> null
- username = "infrahouse8" -> null
}
+ members {
+ role = "member"
+ username = "infrahouse8"
}
# (1 unchanged block hidden)
}
# github_team_members.dev will be updated in-place
~ resource "github_team_members" "dev" {
id = "7332815"
# (1 unchanged attribute hidden)
- members {
- role = "maintainer" -> null
- username = "infrahouse8" -> null
}
+ members {
+ role = "member"
+ username = "infrahouse8"
}
# (2 unchanged blocks hidden)
}
# module.aws_service_infrahouse_app.github_repository_environment.cd["production"] will be created
+ resource "github_repository_environment" "cd" {
+ can_admins_bypass = true
+ environment = "live-production"
+ id = (known after apply)
+ prevent_self_review = false
+ repository = "aws-service-infrahouse-app"
+ repository_id = (known after apply)
}
# module.aws_service_infrahouse_app.github_repository_environment.cd["sandbox"] will be updated in-place
~ resource "github_repository_environment" "cd" {
id = "aws-service-infrahouse-app:live-sandbox"
# (6 unchanged attributes hidden)
- deployment_branch_policy {
- custom_branch_policies = true -> null
- protected_branches = false -> null
}
}
# module.aws_service_infrahouse_app.github_repository_file.makefile_fragment[0] will be updated in-place
~ resource "github_repository_file" "makefile_fragment" {
~ commit_message = "Update makefiles/Makefile" -> "Add makefiles/Makefile"
~ content = <<-EOT
# This file is managed by Terraform in infrahouse/github-control repository.
# Do not edit this file, all changes will be overwritten.
# If you need to add custom targets, create a new file in the makefiles/ directory.
SHELL := /usr/bin/env bash
.DEFAULT_GOAL := help
define PRINT_HELP_PYSCRIPT
import re, sys
for line in sys.stdin:
match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line)
if match:
target, help = match.groups()
print("%-40s %s" % (target, help))
endef
export PRINT_HELP_PYSCRIPT
help: ## Print this help
cat $(MAKEFILE_LIST) | python -c "$$PRINT_HELP_PYSCRIPT"
.PHONY: bootstrap
bootstrap: ## Build development environment
pip install -r requirements.txt
.PHONY: lint
lint: ## Check code style
terraform fmt -check -recursive
.PHONY: format
format: ## Format terraform files
terraform fmt -recursive
.PHONY: init
init:
terraform init
.PHONY: plan
plan: init ## Run terraform plan
set -o pipefail ; terraform plan -no-color --out=tf.plan 2> plan.stderr | tee plan.stdout || (cat plan.stderr; exit 1)
.PHONY: apply
apply: ## Run terraform apply
terraform apply -auto-approve -input=false tf.plan
+ .PHONY: smoke
+ smoke: ## Run post-deploy smoke test if scripts/smoke.sh exists
+ @if [ -x scripts/smoke.sh ]; then \
+ scripts/smoke.sh "$(ENV)"; \
+ else \
+ echo "smoke[$(ENV)]: no scripts/smoke.sh, skipping"; \
+ fi
+
.PHONY: clean
clean: ## Remove generated files
rm -fr .terraform
rm -f .terraform.lock.hcl
rm -f plan.stderr plan.stdout tf.plan
EOT
id = "aws-service-infrahouse-app:makefiles/Makefile:main"
# (8 unchanged attributes hidden)
}
# module.aws_service_infrahouse_app.github_repository_file.terraform_cd[0] will be updated in-place
~ resource "github_repository_file" "terraform_cd" {
~ content = <<-EOT
---
name: "Terraform CD"
on: # yamllint disable-line rule:truthy
pull_request:
types:
- "closed"
permissions:
id-token: "write"
contents: "read"
concurrency:
group: "terraform"
cancel-in-progress: false
jobs:
deploy-order-0:
if: "github.event.pull_request.merged"
strategy:
fail-fast: false
matrix:
env: ["sandbox"]
name: "Terraform Apply ${{ matrix.env }}"
runs-on: ubuntu-24.04
environment: "live-${{ matrix.env }}"
timeout-minutes: 60
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
REGION_JSON: "${{ vars.AWS_DEFAULT_REGION }}"
ROLE_GITHUB_JSON: "${{ vars.ROLE_GITHUB }}"
ROLE_SM_JSON: "${{ vars.ROLE_STATE_MANAGER }}"
TF_VAR_environment: "${{ matrix.env }}"
defaults:
run:
shell: "bash"
steps:
- name: "Checkout"
uses: "actions/checkout@v6"
- name: "Extract Variables"
id: "extract_vars"
run: |
REGION=$(echo '${{ env.REGION_JSON }}' | jq -r '.${{ matrix.env }}')
echo "REGION=$REGION" >> "$GITHUB_OUTPUT"
ROLE_GITHUB=$(echo '${{ env.ROLE_GITHUB_JSON }}' | jq -r '.${{ matrix.env }}')
echo "ROLE_GITHUB=$ROLE_GITHUB" >> "$GITHUB_OUTPUT"
ROLE_SM=$(echo '${{ env.ROLE_SM_JSON }}' | jq -r '.${{ matrix.env }}')
echo "ROLE_STATE_MANAGER=$ROLE_SM" >> "$GITHUB_OUTPUT"
- name: "Configure AWS Credentials"
uses: "aws-actions/configure-aws-credentials@v6"
with:
role-to-assume: "${{ steps.extract_vars.outputs.ROLE_GITHUB }}"
role-session-name: "github-actions-${{ matrix.env }}"
aws-region: "${{ steps.extract_vars.outputs.REGION }}"
- name: "Set Terraform version"
id: "terraform_version"
run: |
echo "IH_TF_VERSION=$(cat .terraform-version)" >> "$GITHUB_OUTPUT"
- name: "Setup Terraform"
uses: "hashicorp/setup-terraform@v4"
with:
terraform_version: "${{ steps.terraform_version.outputs.IH_TF_VERSION }}"
- name: "Set up Python"
uses: "actions/setup-python@v6"
with:
python-version: "3.14"
- name: "Setup Python Environment"
working-directory: "environments/${{ matrix.env }}"
run: |
make bootstrap
- name: "Download Terraform Plan"
working-directory: "environments/${{ matrix.env }}"
run: |
ih-plan \
--aws-assume-role-arn \
${{ steps.extract_vars.outputs.ROLE_STATE_MANAGER }} \
download \
plans/${{ matrix.env }}/${{ github.event.pull_request.number }}.plan \
tf.plan
- name: "Terraform Init"
working-directory: "environments/${{ matrix.env }}"
run: |
terraform init -input=false
- name: "Terraform Validate"
working-directory: "environments/${{ matrix.env }}"
run: |
terraform validate -no-color
- name: "Terraform Apply"
working-directory: "environments/${{ matrix.env }}"
run: |
make apply
- name: "Remove Plan"
working-directory: "environments/${{ matrix.env }}"
run: |
ih-plan \
--aws-assume-role-arn \
${{ steps.extract_vars.outputs.ROLE_STATE_MANAGER }} \
remove \
plans/${{ matrix.env }}/${{ github.event.pull_request.number }}.plan
+
+ - name: "Smoke Test"
+ working-directory: "environments/${{ matrix.env }}"
+ run: |
+ make smoke ENV=${{ matrix.env }}
deploy-order-1:
if: "github.event.pull_request.merged"
needs: ["deploy-order-0"]
strategy:
fail-fast: false
matrix:
env: ["production"]
name: "Terraform Apply ${{ matrix.env }}"
runs-on: ubuntu-24.04
environment: "live-${{ matrix.env }}"
timeout-minutes: 60
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
REGION_JSON: "${{ vars.AWS_DEFAULT_REGION }}"
ROLE_GITHUB_JSON: "${{ vars.ROLE_GITHUB }}"
ROLE_SM_JSON: "${{ vars.ROLE_STATE_MANAGER }}"
TF_VAR_environment: "${{ matrix.env }}"
defaults:
run:
shell: "bash"
steps:
- name: "Checkout"
uses: "actions/checkout@v6"
- name: "Extract Variables"
id: "extract_vars"
run: |
REGION=$(echo '${{ env.REGION_JSON }}' | jq -r '.${{ matrix.env }}')
echo "REGION=$REGION" >> "$GITHUB_OUTPUT"
ROLE_GITHUB=$(echo '${{ env.ROLE_GITHUB_JSON }}' | jq -r '.${{ matrix.env }}')
echo "ROLE_GITHUB=$ROLE_GITHUB" >> "$GITHUB_OUTPUT"
ROLE_SM=$(echo '${{ env.ROLE_SM_JSON }}' | jq -r '.${{ matrix.env }}')
echo "ROLE_STATE_MANAGER=$ROLE_SM" >> "$GITHUB_OUTPUT"
- name: "Configure AWS Credentials"
uses: "aws-actions/configure-aws-credentials@v6"
with:
role-to-assume: "${{ steps.extract_vars.outputs.ROLE_GITHUB }}"
role-session-name: "github-actions-${{ matrix.env }}"
aws-region: "${{ steps.extract_vars.outputs.REGION }}"
- name: "Set Terraform version"
id: "terraform_version"
run: |
echo "IH_TF_VERSION=$(cat .terraform-version)" >> "$GITHUB_OUTPUT"
- name: "Setup Terraform"
uses: "hashicorp/setup-terraform@v4"
with:
terraform_version: "${{ steps.terraform_version.outputs.IH_TF_VERSION }}"
- name: "Set up Python"
uses: "actions/setup-python@v6"
with:
python-version: "3.14"
- name: "Setup Python Environment"
working-directory: "environments/${{ matrix.env }}"
run: |
make bootstrap
- name: "Download Terraform Plan"
working-directory: "environments/${{ matrix.env }}"
run: |
ih-plan \
--aws-assume-role-arn \
${{ steps.extract_vars.outputs.ROLE_STATE_MANAGER }} \
download \
plans/${{ matrix.env }}/${{ github.event.pull_request.number }}.plan \
tf.plan
- name: "Terraform Init"
working-directory: "environments/${{ matrix.env }}"
run: |
terraform init -input=false
- name: "Terraform Validate"
working-directory: "environments/${{ matrix.env }}"
run: |
terraform validate -no-color
- name: "Terraform Apply"
working-directory: "environments/${{ matrix.env }}"
run: |
make apply
- name: "Remove Plan"
working-directory: "environments/${{ matrix.env }}"
run: |
ih-plan \
--aws-assume-role-arn \
${{ steps.extract_vars.outputs.ROLE_STATE_MANAGER }} \
remove \
plans/${{ matrix.env }}/${{ github.event.pull_request.number }}.plan
+
+ - name: "Smoke Test"
+ working-directory: "environments/${{ matrix.env }}"
+ run: |
+ make smoke ENV=${{ matrix.env }}
EOT
id = "aws-service-infrahouse-app:.github/workflows/terraform-CD.yml:main"
# (9 unchanged attributes hidden)
}
Plan: 1 to add, 5 to change, 0 to destroy.
Warning: Argument is deprecated
with module.ih_8_repos.github_repository.repo,
on modules/local-repo/repos.tf line 4, in resource "github_repository" "repo":
4: has_downloads = false
This attribute is no longer in use, but it hasn't been removed yet. It will
be removed in a future version. See
https://github.com/orgs/community/discussions/102145#discussioncomment-8351756
(and 6 more similar warnings elsewhere)
Warning: Deprecated attribute
on .terraform/modules/actions-runner-pem-493370826424-uw1/data_sources.tf line 11, in data "external" "secret_value":
11: "python", "${path.module}/assets/get_secret.py", data.aws_region.current.name, aws_secretsmanager_secret.secret.id, data.aws_iam_role.caller_role.arn
The attribute "name" is deprecated. Refer to the provider documentation for
details.
(and 5 more similar warnings elsewhere)
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: tf.plan
To perform exactly these actions, run the following command to apply:
terraform apply "tf.plan"
metadata
eyJzMzovL2luZnJhaG91c2UtZ2l0aHViLWNvbnRyb2wtc3RhdGUvdGVycmFmb3JtLnRmc3RhdGUiOiB7InN1Y2Nlc3MiOiB0cnVlLCAiYWRkIjogMSwgImNoYW5nZSI6IDUsICJkZXN0cm95IjogMH19
infrahouse8
approved these changes
May 26, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
deploy_orderapproval_team_slugvariable gates reviewers: set it to opt in, leave null (default) for no reviewersdeploy_order > 0only get reviewers whenapproval_team_slugis setmake smoketarget to makefile template (fail-open: no-ops ifscripts/smoke.shmissing)Closes #34
Context
PR #33 hit a 422 from GitHub API because required-reviewer environment protection rules need Enterprise Cloud for private repos. The old code unconditionally added reviewers to any environment with
deploy_order > 0.Now
aws-service-infrahouse-app(private, Team plan) works becauseapproval_team_slugdefaults to null — no reviewers, no 422. Enterprise Cloud orgs can opt in by settingapproval_team_slug.Test plan
terraform planshows no reviewers onlive-production(approval_team_slug not set)make smokeno-ops gracefully whenscripts/smoke.shdoesn't exist🤖 Generated with Claude Code