name: Pipeline on: push: branches: - 'main' - 'feature**' delete: branches: - 'feature**' env: PIPELINE_USER_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} PIPELINE_USER_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} SAM_TEMPLATE: template.yaml TESTING_STACK_NAME: test-stack TESTING_PIPELINE_EXECUTION_ROLE: test-pipeline-execution-role TESTING_CLOUDFORMATION_EXECUTION_ROLE: test-cfn-execution-role TESTING_ARTIFACTS_BUCKET: test-bucket TESTING_IMAGE_REPOSITORY: test-ecr TESTING_REGION: us-east-2 PROD_STACK_NAME: prod-stack PROD_PIPELINE_EXECUTION_ROLE: prod-pipeline-execution-role PROD_CLOUDFORMATION_EXECUTION_ROLE: prod-cfn-execution-role PROD_ARTIFACTS_BUCKET: prod-bucket PROD_IMAGE_REPOSITORY: prod-ecr PROD_REGION: us-west-2 jobs: test: if: github.event_name == 'push' runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: | # trigger the tests here delete-feature: if: startsWith(github.event.ref, 'feature') && github.event_name == 'delete' runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: aws-actions/setup-sam@v2 with: use-installer: true - name: Assume the testing pipeline user role uses: aws-actions/configure-aws-credentials@v1-node16 with: aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }} aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }} aws-region: ${{ env.TESTING_REGION }} role-to-assume: ${{ env.TESTING_PIPELINE_EXECUTION_ROLE }} role-session-name: testing-packaging role-duration-seconds: 3600 role-skip-session-tagging: true - name: Delete feature branch stack env: FEATURE_BRANCH_NAME: ${{ github.event.ref }} run: | sam delete \ --stack-name $(echo ${FEATURE_BRANCH_NAME##*/} | tr -cd '[a-zA-Z0-9-]') \ --region ${TESTING_REGION} \ --no-prompts build-and-deploy-feature: # this stage is triggered only for feature branches (feature*), # which will build the stack and deploy to a stack named with branch name. # https://github.com/actions/setup-python # https://github.com/aws-actions/configure-aws-credentials#notice-node12-deprecation-warning if: startsWith(github.ref, 'refs/heads/feature') needs: [test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: aws-actions/setup-sam@v2 with: use-installer: true - run: sam build --template ${SAM_TEMPLATE} --use-container - name: Assume the testing pipeline user role uses: aws-actions/configure-aws-credentials@v1-node16 with: aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }} aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }} aws-region: ${{ env.TESTING_REGION }} role-to-assume: ${{ env.TESTING_PIPELINE_EXECUTION_ROLE }} role-session-name: feature-deployment role-duration-seconds: 3600 role-skip-session-tagging: true - name: Deploy to feature stack in the testing account shell: bash run: | sam deploy --stack-name $(echo ${GITHUB_REF##*/} | tr -cd '[a-zA-Z0-9-]') \ --capabilities CAPABILITY_IAM \ --region ${TESTING_REGION} \ --s3-bucket ${TESTING_ARTIFACTS_BUCKET} \ --image-repository ${TESTING_IMAGE_REPOSITORY} \ --no-fail-on-empty-changeset \ --role-arn ${TESTING_CLOUDFORMATION_EXECUTION_ROLE} build-and-package: if: github.ref == 'refs/heads/main' needs: [test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: aws-actions/setup-sam@v2 with: use-installer: true - name: Build resources run: sam build --template ${SAM_TEMPLATE} --use-container - name: Assume the testing pipeline user role uses: aws-actions/configure-aws-credentials@v1-node16 with: aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }} aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }} aws-region: ${{ env.TESTING_REGION }} role-to-assume: ${{ env.TESTING_PIPELINE_EXECUTION_ROLE }} role-session-name: testing-packaging role-duration-seconds: 3600 role-skip-session-tagging: true - name: Upload artifacts to testing artifact buckets run: | sam package \ --s3-bucket ${TESTING_ARTIFACTS_BUCKET} \ --image-repository ${TESTING_IMAGE_REPOSITORY} \ --region ${TESTING_REGION} \ --output-template-file packaged-testing.yaml - uses: actions/upload-artifact@v3 with: name: packaged-testing.yaml path: packaged-testing.yaml - name: Assume the prod pipeline user role uses: aws-actions/configure-aws-credentials@v1-node16 with: aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }} aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }} aws-region: ${{ env.PROD_REGION }} role-to-assume: ${{ env.PROD_PIPELINE_EXECUTION_ROLE }} role-session-name: prod-packaging role-duration-seconds: 3600 role-skip-session-tagging: true - name: Upload artifacts to production artifact buckets run: | sam package \ --s3-bucket ${PROD_ARTIFACTS_BUCKET} \ --image-repository ${PROD_IMAGE_REPOSITORY} \ --region ${PROD_REGION} \ --output-template-file packaged-prod.yaml - uses: actions/upload-artifact@v3 with: name: packaged-prod.yaml path: packaged-prod.yaml deploy-testing: if: github.ref == 'refs/heads/main' needs: [build-and-package] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: aws-actions/setup-sam@v2 with: use-installer: true - uses: actions/download-artifact@v3 with: name: packaged-testing.yaml - name: Assume the testing pipeline user role uses: aws-actions/configure-aws-credentials@v1-node16 with: aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }} aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }} aws-region: ${{ env.TESTING_REGION }} role-to-assume: ${{ env.TESTING_PIPELINE_EXECUTION_ROLE }} role-session-name: testing-deployment role-duration-seconds: 3600 role-skip-session-tagging: true - name: Deploy to testing account run: | sam deploy --stack-name ${TESTING_STACK_NAME} \ --template packaged-testing.yaml \ --capabilities CAPABILITY_IAM \ --region ${TESTING_REGION} \ --s3-bucket ${TESTING_ARTIFACTS_BUCKET} \ --image-repository ${TESTING_IMAGE_REPOSITORY} \ --no-fail-on-empty-changeset \ --role-arn ${TESTING_CLOUDFORMATION_EXECUTION_ROLE} integration-test: if: github.ref == 'refs/heads/main' needs: [deploy-testing] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: | # trigger the integration tests here deploy-prod: if: github.ref == 'refs/heads/main' needs: [integration-test] runs-on: ubuntu-latest # Configure GitHub Action Environment to have a manual approval step before deployment to production # https://docs.github.com/en/actions/reference/environments # environment: steps: - uses: actions/checkout@v3 - uses: aws-actions/setup-sam@v2 with: use-installer: true - uses: actions/download-artifact@v3 with: name: packaged-prod.yaml - name: Assume the prod pipeline user role uses: aws-actions/configure-aws-credentials@v1-node16 with: aws-access-key-id: ${{ env.PIPELINE_USER_ACCESS_KEY_ID }} aws-secret-access-key: ${{ env.PIPELINE_USER_SECRET_ACCESS_KEY }} aws-region: ${{ env.PROD_REGION }} role-to-assume: ${{ env.PROD_PIPELINE_EXECUTION_ROLE }} role-session-name: prod-deployment role-duration-seconds: 3600 role-skip-session-tagging: true - name: Deploy to production account run: | sam deploy --stack-name ${PROD_STACK_NAME} \ --template packaged-prod.yaml \ --capabilities CAPABILITY_IAM \ --region ${PROD_REGION} \ --s3-bucket ${PROD_ARTIFACTS_BUCKET} \ --image-repository ${PROD_IMAGE_REPOSITORY} \ --no-fail-on-empty-changeset \ --role-arn ${PROD_CLOUDFORMATION_EXECUTION_ROLE}