.github/.github/workflows/cd-sam.yaml
Adam Moussa 4d2ab6f32e Add post-deploy health checks to CD workflows
Verifies stack status after deploy, prints outputs, and runs
project-specific scripts/health-check.sh if present.
2026-05-14 18:34:46 -04:00

122 lines
3.9 KiB
YAML

name: CD — SAM Deploy
on:
workflow_call:
inputs:
python-version:
description: "Python version to use"
type: string
default: "3.12"
stack-name:
description: "CloudFormation stack name"
type: string
required: true
sam-template:
description: "Path to SAM template file"
type: string
default: "template.yaml"
region:
description: "AWS region"
type: string
default: "us-east-1"
cfn-role-arn:
description: "CloudFormation execution role ARN"
type: string
required: true
secrets:
deploy-role-arn:
description: "OIDC deploy role ARN"
required: true
parameter-overrides:
description: "SAM parameter overrides (e.g. 'Key1=Value1 Key2=Value2')"
required: false
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
- uses: aws-actions/setup-sam@v2
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.deploy-role-arn }}
aws-region: ${{ inputs.region }}
- name: Pre-flight checks
run: |
echo "Pre-flight: checking stack ${{ inputs.stack-name }}..."
STATUS=$(aws cloudformation describe-stacks \
--stack-name "${{ inputs.stack-name }}" \
--query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NOT_FOUND")
case "$STATUS" in
*ROLLBACK_COMPLETE|*FAILED)
echo "::error::Stack ${{ inputs.stack-name }} is in $STATUS — manual intervention required."
exit 1
;;
*IN_PROGRESS)
echo "::error::Stack ${{ inputs.stack-name }} has an operation in progress ($STATUS) — wait for it to complete."
exit 1
;;
NOT_FOUND)
echo "Pre-flight: stack not found — will be created on first deploy."
;;
*)
echo "Pre-flight: stack status is $STATUS — OK to deploy."
;;
esac
- name: SAM build
run: sam build --template ${{ inputs.sam-template }}
- name: SAM deploy
run: |
PARAMS=""
if [ -n "${{ secrets.parameter-overrides }}" ]; then
PARAMS="--parameter-overrides ${{ secrets.parameter-overrides }}"
fi
sam deploy \
--stack-name ${{ inputs.stack-name }} \
--template-file .aws-sam/build/template.yaml \
--resolve-s3 \
--capabilities CAPABILITY_IAM \
--no-confirm-changeset \
--no-fail-on-empty-changeset \
--role-arn ${{ inputs.cfn-role-arn }} \
$PARAMS
- name: Post-deploy health check
run: |
echo "Health check: verifying stack ${{ inputs.stack-name }}..."
STATUS=$(aws cloudformation describe-stacks \
--stack-name "${{ inputs.stack-name }}" \
--query 'Stacks[0].StackStatus' --output text)
if [[ "$STATUS" != *"COMPLETE" ]] || [[ "$STATUS" == *"ROLLBACK"* ]]; then
echo "::error::Stack ${{ inputs.stack-name }} ended in $STATUS after deploy."
exit 1
fi
echo "Stack status: $STATUS"
echo "Stack outputs:"
aws cloudformation describe-stacks \
--stack-name "${{ inputs.stack-name }}" \
--query 'Stacks[0].Outputs[*].[OutputKey,OutputValue]' --output table
# Run project-specific health check if it exists
if [[ -f scripts/health-check.sh ]]; then
echo "Running project health check..."
bash scripts/health-check.sh "${{ inputs.stack-name }}" "${{ inputs.region }}"
fi
echo "Health check passed."