.github/workflows/deploy.yml
name: Deploy
on:
push:
branches:
- "*"
- "!skipci*"
concurrency:
group: ${{ github.ref_name }}-group
env:
STAGE_NAME: ${{ github.ref_name }}
permissions:
id-token: write
contents: write
issues: write
pull-requests: write
jobs:
init:
runs-on: ubuntu-20.04
steps:
- name: Validate stage name
run: |
if [[ ! $STAGE_NAME =~ ^[a-z][a-z0-9-]*$ ]]; then
echo "ERROR: Your branch name, $STAGE_NAME, is not a valid Serverless Framework stage name." && exit 1
fi
deploy:
runs-on: ubuntu-20.04
needs:
- init
environment:
name: ${{ github.ref_name }}
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: ./.github/actions/setup
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_TO_ASSUME }}
aws-region: us-east-1
role-duration-seconds: 10800
- name: Deploy
run: run deploy --stage $STAGE_NAME
test:
runs-on: ubuntu-20.04
needs:
- deploy
environment:
name: ${{ github.ref_name }}
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: ./.github/actions/setup
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_TO_ASSUME }}
aws-region: us-east-1
role-duration-seconds: 10800
- name: Test
run: run test --stage $STAGE_NAME
cfn-nag:
runs-on: ubuntu-20.04
needs:
- deploy
environment:
name: ${{ github.ref_name }}
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: ./.github/actions/setup
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_TO_ASSUME }}
aws-region: us-east-1
role-duration-seconds: 10800
- name: Get CloudFormation templates
id: getCfts
run: |
mkdir -p cftemplates
stackList=(`aws cloudformation describe-stacks --query "Stacks[?Tags[?Key=='STAGE' && Value=='$STAGE_NAME'] && Tags[?Key=='PROJECT' && Value=='$PROJECT']].StackName" --output text`)
for stack in "${stackList[@]}"; do
aws cloudformation get-template --stack-name "$stack" --query TemplateBody > "cftemplates/${stack}.json"
done
- name: Stelligent cfn_nag
uses: stelligent/cfn_nag@v0.8.6
with:
input_path: cftemplates
resources:
runs-on: ubuntu-20.04
needs:
- deploy
environment:
name: ${{ github.ref_name }}
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: ./.github/actions/setup
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_TO_ASSUME }}
aws-region: us-east-1
role-duration-seconds: 10800
- name: Get AWS Stage Resources
id: stage-resources
run: |
mkdir -p resources
resourceData=()
stackList=(`aws cloudformation describe-stacks --query "Stacks[?Tags[?Key=='STAGE' && Value=='$STAGE_NAME'] && Tags[?Key=='PROJECT' && Value=='$PROJECT']].StackName" --output text`)
for stack in "${stackList[@]}"; do
resources=$(aws cloudformation list-stack-resources --stack-name "$stack" --query "StackResourceSummaries[].{PhysicalResourceId:PhysicalResourceId, ResourceType:ResourceType, ResourceStatus:ResourceStatus, LogicalResourceId:LogicalResourceId, LastUpdatedTimestamp:LastUpdatedTimestamp}" --output json)
resourceData+=( $(echo "$resources" | jq -c --arg stack_name "$stack" '.[] + { StackName: $stack_name }') )
done
join_by() { local IFS="$1"; shift; echo "$*"; }
echo "["$(join_by "," "${resourceData[@]}")"]" > "resources/aws-resources.json"
- name: Archive stage resources
uses: actions/upload-artifact@v3
with:
name: aws-resources-${{ github.ref_name }}
path: resources/aws-resources.json
release:
runs-on: ubuntu-20.04
needs:
- test
- cfn-nag
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: ./.github/actions/setup
- name: Release
run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
notify_of_failure:
runs-on: ubuntu-20.04
needs:
- release
if: failure()
steps:
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
if: env.SLACK_WEBHOOK != '' && contains(fromJson('["master", "val", "production"]'), env.STAGE_NAME)
env:
SLACK_COLOR: ${{job.status}}
SLACK_ICON: https://github.com/Enterprise-CMCS.png?size=48
SLACK_TITLE: Failure
SLACK_USERNAME: ${{ github.repository }} - ${{job.status}}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}