I am working with GitHub to deploy a container based application on multiple environments, I have two environments,
- Dev
- Prod
I am building the application on both the Environments, this is my yml file:
name: 'Manual - Build & Deploy - Enterprise'
on:
push:
branches-ignore:
- '**'
workflow_dispatch:
inputs:
git-ref:
description: Git Ref (Optional)
default: develop
required: false
account:
description: slb-dev, slb-prod
default: slb-dev
required: true
environment:
description: development (main, int, qs), production (v1_demo, v1_rosecity, demo)
default: main
required: false
microservice:
description: chroma, liquid, tenant, dashboard, lims, lims-simulator, client, logging, metrc
default: chroma
required: false
builddir:
description: MicroChromatographyService/MicroChromatographyService, MicroLiquidHandlingService/MicroLiquidHandlingService, MicroTenantService/MicroTenantService, MicroDashboardService/MicroDashboardService, LIMSIntegrationService/LIMSIntegrationService, LIMSSimulatorService/LIMSSimulatorService, IntegrationHubClientService/IntegrationHubClientService, PerkinElmer.LoggingService/PerkinElmer.LoggingService, MetRCReportService/MetRCReportService
default: MicroChromatographyService/MicroChromatographyService
required: false
jobs:
setup:
name: Setup ENV Variables
runs-on: ubuntu-latest
environment:
name: dev
url: https://dev.test.com
steps:
- name: Set Vars
id: setvars
run: |
echo "::set-output name=APP_NAME::${{ github.event.inputs.microservice }}"
echo "::set-output name=AWS_REGION::us-east-1"
echo "::set-output name=SHA8::${{ github.sha }} | cut -c1-8)"
echo "::set-output name=BUILD_DIR::${{ github.event.inputs.builddir }}"
echo "::set-output name=ECR_REPOSITORY::${{ github.event.inputs.account }}-${{ github.event.inputs.environment }}-${{ github.event.inputs.microservice }}"
echo "::set-output name=ECS_CLUSTER::${{ github.event.inputs.account }}-${{ github.event.inputs.environment }}"
echo "::set-output name=ECS_SERVICE::${{ github.event.inputs.account }}-${{ github.event.inputs.environment }}-${{ github.event.inputs.microservice }}"
echo "::set-output name=ECS_TASK_DEFINITION::${{ github.event.inputs.account }}-${{ github.event.inputs.environment }}-${{ github.event.inputs.microservice }}"
echo "::set-output name=ECS_TASK_DEFINITION_FILE::task-definition-${{ github.event.inputs.microservice }}.json"
echo "::set-output name=ECS_CONTAINER_NAME::${{ github.event.inputs.account }}-${{ github.event.inputs.environment }}-${{ github.event.inputs.microservice }}"
outputs:
APP_NAME: ${{ steps.setvars.outputs.APP_NAME }}
AWS_REGION: ${{ steps.setvars.outputs.AWS_REGION }}
SHA8: ${{ steps.setvars.outputs.SHA8 }}
BUILD_DIR: ${{ steps.setvars.outputs.BUILD_DIR }}
ECR_REPOSITORY: ${{ steps.setvars.outputs.ECR_REPOSITORY }}
ECS_CLUSTER: ${{ steps.setvars.outputs.ECS_CLUSTER }}
ECS_SERVICE: ${{ steps.setvars.outputs.ECS_SERVICE }}
ECS_TASK_DEFINITION: ${{ steps.setvars.outputs.ECS_TASK_DEFINITION }}
ECS_TASK_DEFINITION_FILE: ${{ steps.setvars.outputs.ECS_TASK_DEFINITION_FILE }}
ECS_CONTAINER_NAME: ${{ steps.setvars.outputs.ECS_CONTAINER_NAME }}
DeployDev:
name: Deploy to Dev
needs: setup
runs-on: ubuntu-latest
permissions:
packages: write
contents: write
id-token: write
environment:
name: dev
url: 'http://dev.myapp.com'
steps:
- name: Set Environments
run: |
if [[ "${{github.event.inputs.account}}" == "slb-dev" ]]; then
echo "AWS_ACCESS_KEY_ID=${{ env.AWS_ACCESS_KEY_ID_DEV }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ env.AWS_SECRET_ACCESS_KEY_DEV }}" >> $GITHUB_ENV
fi
if [[ "${{github.event.inputs.account}}" == "slb-prod" ]]; then
echo "AWS_ACCESS_KEY_ID=${{ env.AWS_ACCESS_KEY_ID_PROD }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ env.AWS_SECRET_ACCESS_KEY_PROD }}" >> $GITHUB_ENV
fi
- name: Clone Repository (Current branch)
uses: actions/checkout@v2
if: github.event.inputs.git-ref == ''
- name: Clone Repository (Custom Ref)
uses: actions/checkout@v2
if: github.event.inputs.git-ref != ''
with:
ref: ${{ github.event.inputs.git-ref }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ needs.setup.outputs.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ needs.setup.outputs.ECR_REPOSITORY }}
IMAGE_TAG: ${{ github.sha }}
run: |
cd ${{ needs.setup.outputs.BUILD_DIR }}
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -t $ECR_REGISTRY/$ECR_REPOSITORY:latest .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
- name: Download task definition
run: |
aws ecs describe-task-definition --task-definition ${{ needs.setup.outputs.ECS_TASK_DEFINITION }} --query taskDefinition > ${{ needs.setup.outputs.ECS_TASK_DEFINITION_FILE }}
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ needs.setup.outputs.ECS_TASK_DEFINITION_FILE }}
container-name: ${{ needs.setup.outputs.ECS_CONTAINER_NAME }}
image: ${{ steps.build-image.outputs.image }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: ${{ needs.setup.outputs.ECS_SERVICE }}
cluster: ${{ needs.setup.outputs.ECS_CLUSTER }}
wait-for-service-stability: true
DeployProd:
name: Deploy to Production
needs: [DeployDev]
runs-on: ubuntu-latest
permissions:
packages: write
contents: write
id-token: write
environment:
name: Production
url: 'http://www.myapp.com'
steps:
- name: Set Environments
run: |
if [[ "${{github.event.inputs.account}}" == "slb-dev" ]]; then
echo "AWS_ACCESS_KEY_ID=${{ env.AWS_ACCESS_KEY_ID_DEV }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ env.AWS_SECRET_ACCESS_KEY_DEV }}" >> $GITHUB_ENV
fi
if [[ "${{github.event.inputs.account}}" == "slb-prod" ]]; then
echo "AWS_ACCESS_KEY_ID=${{ env.AWS_ACCESS_KEY_ID_PROD }}" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=${{ env.AWS_SECRET_ACCESS_KEY_PROD }}" >> $GITHUB_ENV
fi
- name: Clone Repository (Current branch)
uses: actions/checkout@v2
if: github.event.inputs.git-ref == ''
- name: Clone Repository (Custom Ref)
uses: actions/checkout@v2
if: github.event.inputs.git-ref != ''
with:
ref: ${{ github.event.inputs.git-ref }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ needs.setup.outputs.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ needs.setup.outputs.ECR_REPOSITORY }}
IMAGE_TAG: ${{ github.sha }}
run: |
cd ${{ needs.setup.outputs.BUILD_DIR }}
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -t $ECR_REGISTRY/$ECR_REPOSITORY:latest .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
- name: Download task definition
run: |
aws ecs describe-task-definition --task-definition ${{ needs.setup.outputs.ECS_TASK_DEFINITION }} --query taskDefinition > ${{ needs.setup.outputs.ECS_TASK_DEFINITION_FILE }}
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ needs.setup.outputs.ECS_TASK_DEFINITION_FILE }}
container-name: ${{ needs.setup.outputs.ECS_CONTAINER_NAME }}
image: ${{ steps.build-image.outputs.image }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: ${{ needs.setup.outputs.ECS_SERVICE }}
cluster: ${{ needs.setup.outputs.ECS_CLUSTER }}
wait-for-service-stability: true
But I am getting the error: when trying to log in, I am not sure what might be causing that. I am calling the credentials from GitHub Secrets, and it seems to be working when doing a separate build but when I try to do it with different environments I get this error.
CodePudding user response:
Until recent update aws actions required aws creds to be configured as github repo secret. After which it sets up as those creds in to env vars which makes them accessible in entire github action.
In your yml file it should be like this
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secret.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secret.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ needs.setup.outputs.AWS_REGION }}
Note [IMP]: in the recent update, aws-actions now supports OIDC feature, which enables us to use role instead of storing creds in our repo which is considered now a bad practice. Docs for ref -> https://github.com/aws-actions/configure-aws-credentials#assuming-a-role
i wrote a similar answer to OIDC problem maybe it can help How to use serverless framework in github actions using github actions OIDC feature