Skip to content

Continuous Delivery

flowchart LR
    DS1[DEPLOY TO TEST] DS1DP1@--| --> DP1[DEPLOY TO PROD]

    style DS1 fill:#43F8B6,color:#fff,stroke:none
    style DP1 fill:#F9C66B,color:#fff,stroke:none

In GitHub Actions, Continuous Delivery can be implemented by creating two separate GitHub Actions Workflows as follows:

First workflow:

flowchart LR
    build@{ label: "Build Image" }
    subgraph CI["Shared Account"]
        ecr@{ label: "ECR" }
    end
    build X@-.-> |Job 1| ecr

    subgraph TEST[AWS — Test Account]
        ecs_test@{ label: "Service" }
    end

    ecr Y@-.-> |Job 2| ecs_test

    X@{ animation: fast }
    Y@{ animation: fast }

    style CI fill:none,stroke:#1a5fe0
    style TEST fill:#fff8f0,stroke:#FF9900

Second workflow:

flowchart LR
    manual@{ shape: "manual-input", label: "User" }
    subgraph CI["Shared Account"]
        ecr@{ label: "ECR" }
    end
    manual -.-> |Manual trigger| ecr

    subgraph PROD[AWS — Prod Account]
        prod@{ label: "Service" }
    end

    ecr Y@-.-> |Job 1| prod

    Y@{ animation: fast }

    style CI fill:none,stroke:#1a5fe0
    style PROD fill:#fff0f0,stroke:#cc0000

Splitting the pipeline in this manner ensures that deployment to PROD is controlled.

Code Examples

First workflow: deploy_to_test.yml

.github/workflows/deploy_to_test.yml
name: Deploy to TEST

on:
  push:
    branches: [master]
  workflow_dispatch:

jobs:
  build_push_image_to_shared:
    name: Build image and publish to ECR
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: "Service A"
        uses: BYM-IKT/github-actions/build-and-push-image-to-ecr@master
        with:
          aws-account-id:      "<<AWS_ACCOUNT_ID_TEST>>"        
          ecr-name:            <<ECR_REPOSITORY_NAME>>
          docker-context-path: <<DOCKER_CONTEXT_PATH>>

  deploy_images_to_ecs_service_test:
    needs: [build_push_image_to_shared]
    name: "Deploy to TEST"
    uses: BYM-IKT/github-actions/.github/workflows/deploy-image-to-ecs.yml@v0
    with:
      environment:              testing
      aws-account-id-target:    "<<AWS_ACCOUNT_ID_TEST>>"
      ecr-name:                 <<ECR_REPOSITORY_NAME>>
      image-tag-target:         latest
      image-tag-new:            test
      ecs-cluster-name:         <<ECS_CLUSTER_NAME_TEST>>
      ecs-service-name:         <<ECS_SERVICE_NAME_TEST>>
.github/workflows/deploy_to_test.yml
name: Deploy to TEST

on:
  push:
    branches: [master]
  workflow_dispatch:

jobs:
  build_push_image_to_shared:
    name: Build image and publish to ECR
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: "Service A"
        uses: BYM-IKT/github-actions/build-and-push-image-to-ecr@master
        with:
          aws-account-id:      "<<AWS_ACCOUNT_ID_TEST>>"        
          ecr-name:            <<ECR_REPOSITORY_NAME>>
          docker-context-path: <<DOCKER_CONTEXT_PATH>>

  deploy_image_to_lambda_function_test:
    needs: [build_push_image_to_shared]
    name: "Deploy to TEST"
    uses: BYM-IKT/github-actions/.github/workflows/deploy-image-to-lambda.yml@v0
    with:
      environment:              testing 
      aws-account-id-target:    <<AWS_ACCOUNT_ID_TEST>>
      ecr-name:                 <<ECR_REPOSITORY_NAME>>
      image-tag-target:         latest
      image-tag-new:            test
      lambda-name:              <<LAMBDA_FUNCTION_NAME_TEST>>

Second workflow: deploy_to_prod.yml

Take note that the the only trigger configured in this workflow is the workflow_dispatch trigger.

.github/workflows/deploy_to_prod.yml
name: Deploy to PROD

on:
  workflow_dispatch:

jobs:
  deploy_images_to_ecs_service_prod:
    name: "Deploy to PROD"
    uses: BYM-IKT/github-actions/.github/workflows/deploy-image-to-ecs.yml@v0
    with:
      environment:              testing
      aws-account-id-target:    "<<AWS_ACCOUNT_ID_PROD>>"
      ecr-name:                 <<ECR_REPOSITORY_NAME>>
      image-tag-target:         test
      image-tag-new:            prod
      ecs-cluster-name:         <<ECS_CLUSTER_NAME_PROD>>
      ecs-service-name:         <<ECS_SERVICE_NAME_PROD>>
.github/workflows/deploy_to_prod.yml
name: Deploy to PROD

on:
  workflow_dispatch:

jobs:
  deploy_image_to_lambda_function_prod:
    name: "Deploy to PROD"
    uses: BYM-IKT/github-actions/.github/workflows/deploy-image-to-lambda.yml@v0
    with:
      environment:              production 
      aws-account-id-target:    <<AWS_ACCOUNT_ID_PROD>>
      ecr-name:                 <<ECR_REPOSITORY_NAME>>
      image-tag-target:         test
      image-tag-new:            prod
      lambda-name:              <<LAMBDA_FUNCTION_NAME_PROD>>