Home > Software engineering >  GitHub Actions for multiple Environments
GitHub Actions for multiple Environments

Time:12-23

I am working with GitHub to deploy a container based application on multiple environments, I have two environments,

  1. Dev
  2. 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: enter image description here 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

  • Related