Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,37 @@ jobs:
test "$(echo "$PAYLOAD" | jq -r '.data.attributes.git.commit_sha')" = "$GITHUB_SHA"
test "$(echo "$PAYLOAD" | jq -r '.data.attributes.git.repository_url')" = "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY"

- name: Run terraform-deploy with non-trunk tag targeting prod
# Safety check: an `xx-` artifact (built off a non-default branch) must never
# reach prod, regardless of trigger. The action should fail before any AWS work.
id: deploy-blocked
continue-on-error: true
uses: ./terraform-deploy
with:
config: |
{
"prod": {
"accountId": "210987654321",
"defaultRegion": "us-east-1",
"deploymentRoleArn": "arn:aws:iam::210987654321:role/test",
"name": "test-prod"
}
}
stack-dir: "test-stack"
environment: "prod"
tag: "xx-test-app-20260101000000-12345-abcdef12-feature"
github-deploy-key: ${{ steps.ssh-key.outputs.private-key }}
cancel-if-stale: "false"
send-deployment-metric: "false"

- name: Verify non-trunk prod deploy was rejected
env:
OUTCOME: ${{ steps.deploy-blocked.outcome }}
BLOCKED: ${{ steps.deploy-blocked.outputs.__internal-block-unsafe-deployment-result }}
run: |
test "$BLOCKED" = "true"
test "$OUTCOME" = "failure"

test-e2e-terraform-deploy-regression-test-terraform-v1-15-0:
# Regression test for hashicorp/terraform#38484: Terraform 1.15.0 emits the
# S3 backend's `dynamodb_table` deprecation warning to stdout, contaminating
Expand Down
33 changes: 23 additions & 10 deletions terraform-deploy/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ outputs:
__internal-datadog-dora-result:
description: "For internal use. Datadog DORA event payload"
value: ${{ steps.datadog-dora.outputs.result }}
__internal-block-unsafe-deployment-result:
description: "For internal use. 'true' if the deploy was rejected by the unsafe-deployment safety check."
value: ${{ steps.block-unsafe-deployment.outputs.result }}

runs:
using: composite
Expand All @@ -61,20 +64,28 @@ runs:
shell: bash --noprofile --norc -euo pipefail {0}
run: echo "timestamp=$(date +%s)" >> "$GITHUB_OUTPUT"

- name: "Validate manual artifact deploy"
# Deploying a custom tag is outside the normal flow: surface a notice for debugging,
# and refuse to deploy non-default-branch (`xx-`) artifacts to critical environments.
if: ${{ github.event.inputs.artifact-tag != ''}}
- name: "Block unsafe deployment"
# Refuse to deploy artifacts that originate from outside of trunk (`xx-`)
# to critical environments
id: block-unsafe-deployment
if: ${{ inputs.environment == 'prod' && startsWith(inputs.tag, 'xx-') }}
shell: bash --noprofile --norc -euo pipefail {0}
env:
TAG: ${{ inputs.tag }}
ENVIRONMENT: ${{ inputs.environment }}
run: |
echo "result=true" >> "$GITHUB_OUTPUT"
echo "::error title=Deploy to $ENVIRONMENT::An artifact built outside of trunk ($TAG) cannot be deployed to a critical environment"
exit 1

- name: "Notice manual artifact deploy"
# Deploying a custom tag via workflow_dispatch is outside the normal flow: surface a notice for debugging.
if: ${{ github.event.inputs.artifact-tag != '' }}
shell: bash --noprofile --norc -euo pipefail {0}
env:
ARTIFACT_TAG: ${{ github.event.inputs.artifact-tag }}
ENVIRONMENT: ${{ inputs.environment }}
BLOCK_DEPLOYMENT: ${{ inputs.environment == 'prod' && startsWith(inputs.tag, 'xx-') }}
run: |
if [ "$BLOCK_DEPLOYMENT" = "true" ]; then
echo "::error title=Deploy to $ENVIRONMENT::An artifact built outside of trunk ($ARTIFACT_TAG) cannot be deployed to a critical environment"
exit 1
fi
echo "::notice title=Deploy to $ENVIRONMENT::Deployment was manually triggered with the artifact tag: $ARTIFACT_TAG"

- name: Cancel if stale
Expand Down Expand Up @@ -216,7 +227,9 @@ runs:
echo "result=$result" >> "$GITHUB_OUTPUT"

- name: Send deployment metric to Datadog
if: ${{ always() && inputs.send-deployment-metric == 'true' && inputs.datadog-api-key != '' }}
# Skip when a manual deploy was rejected by policy (e.g., `xx-` artifact to prod):
# that's an expected refusal, not a deploy outcome we want in the metric.
if: ${{ always() && steps.block-unsafe-deployment.outputs.result != 'true' && inputs.send-deployment-metric == 'true' && inputs.datadog-api-key != '' }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Måtte scrolle opp litt for å forstå steps.block-unsafe-deployment.outputs.result != 'true'.

steps.block-unsafe-deployment.outputs.result != 'true'

kunne vært noe sånt som

steps.block-unsafe-deployment.outputs.blocked != 'true'

eller

steps.block-unsafe-deployment.outputs.blocked == 'false'

for lettere lesbarhet.

shell: bash --noprofile --norc -euo pipefail {0}
continue-on-error: true
env:
Expand Down
Loading