Giter Club home page Giter Club logo

aws_codepipeline-image-cicd's Introduction

AWS_CodePipeline-IMAGE-CICD

Overview

This is a serverless Docker image CICD application created from AWS SAM template (AWS Cloud Formation), this project consists of AWS serverless services and development codes that will be used in the image CICD pipeline, for instance: CodePipeline, CodeBuild project, Lambda Functions, etc. cicd_workflow.png

Table of Contents

Prerequisites

Building

  • Build the sam application.
$ sam build

Deploying

  1. When you see Build Succeeded from the last step, deploy the sam application to AWS cloud.
$ sam deploy
Deploy this changeset? [y/N]: y
  1. As long as all resources are created, you will see the following output.
Successfully created/updated stack

Update Image

  1. Use the build_cicd.sh shell script in the target image repository to push a new version of image to DEV ECR repo.
$ ./build.sh
  1. After pushing the image to AWS ECR, you can start monitoring the Image CICD process on AWS CodePipeline console.

Rollback Image

  1. Use rollback.sh shell script in the scripts folder to rollback versions in ECR repos.
$ ./rollback.sh
  1. Select the ECR environment you want to rollback by entering option number.
Please select the ECR environment you want to rollback by entering option number:
1) ecr-dev
2) ecr-test
3) ecr-prod
#?
  1. Select the ECR image you want to rollback by entering option number.
Please select the ECR image you want to rollback by entering option number:
1) repo-1
2) repo-2
3) repo-3
#?
Chosen ECR environment: dev
Chosen ECR image: repo-1
Confirm rollback in ecr-dev/repo-1? (y/n): y
  1. After confirming rollback, you can see the output and results from the rollback lambda function.
Rollback from v0.15 to v0.14
Rollback completed

Elaboration

[Source Stage]

  1. The Image CICD pipeline will be automatically triggered by an EventBridge Rule if the LATEST version image in any of the following ECR repos has been updated.
    • ecr-dev/repo-1
    • ecr-dev/repo-2
    • ecr-dev/repo-3
    • ecr-dev/repo-4

[Test Stage]

  1. Whenever the Test stage receives a new update from the Source stage, it sends a notification via SNS and waits for manual approval to proceed.
  2. After receiving approval from the user, the Test stage begins building and pushing the updated image in DEV repo to TEST repo.
  3. Following the success of image pushing, the Test stage invokes the test statemachine for testing the updated image in the Test repo.

[Production Stage]

  1. After successfully proceeding with all of the above tasks and tests, the Production stage sends a notification via SNS and waits for manual approval to deploy.
  2. After receiving approval from the user, the Production stage begins building and pushing the updated image from Test repo to Production repo.

Modifying Pipeline

  • Adding new ECR repos to Image CICD pipeline

  1. Create new repos for dev, test and prod on AWS ECR respectively. nomenclature:
    ecr-dev/new-repo
    ecr-test/new-repo
    ecr-prod/rnew-repo

  2. Find the EcrEventRule in template.yaml file, which defines the ECR repos that EventBridge Rule monitors.

# EcrEventRule (Partial)
EcrEventRule:
  Type: AWS::Events::Rule
  Properties:
    Description: Event rule to automatically start image-cicd-pipeline when new changes occur in ECRs.
    EventBusName: default
    EventPattern:
      source:
        - aws.ecr
      detail:
        action-type:
          - PUSH
        image-tag:
          - latest
        repository-name:
          - ecr-dev/repo-1
  1. At the repository-name section, add new ECR DEV repo names.
# EcrEventRule (Partial)
        repository-name:
          - ecr-dev/repo-1
          - ecr-dev/new-repo
  1. Add new image options to rollback.sh shell script in the scripts folder.
# rollback.sh (Partial)
# Define the ECR repo options
options=("repo" "new-repo")
# rollback.sh (Partial)
# Prompt the user to select an ECR image
select image in "${options_image[@]}"; do
    case $image in
        "repo")
            chosen_option_image="repo"
            break
            ;;
        "new-repo")
            chosen_option_image="new-repo"
            break
            ;;
        *)
            echo "Invalid option"
            ;;
    esac
done
  1. Build and deploy the sam application again.
$ sam build
$ sam deploy
Deploy this changeset? [y/N]: y
Successfully updated stack

  • Modifying image-cicd-pipeline from AWS Management Console

  1. This CICD application is designed to be updated and deployed from AWS CloudFormation template, please avoid modifying the application from AWS Management Console or AWS CLI.
  2. If necessary, after modifying from CodePipeline Console, you will encounter below confirmation:
Source action changed
We will update the following resources to detect changes for your updated pipeline.
Add | Pipeline image-cicd-pipeline as a target to Amazon CloudWatch Events rule
  1. Please check the checkbox and ensure No resource updates needed for this source action change to avoid AWS automatically overrides the settings of EventBridge Rule.
V | No resource updates needed for this source action change

Usage

buildspec.yml

The buildspec.yml file specifies respective building commands in different stage to build and push images.

version: 0.2
env:
  shell: bash
phases:
  build:
    commands:
      # Pushing ECR image to TEST/PROD repo
      # ECR image Update strategy:
      # 1. Get the last numerical version number before LATEST
      # 2. Retag numerical version number to current LATEST
      # 3. Push the new image to ECR (ECR auto update LATEST tag)
      # Get current pipeline execution id from cli
      - exec_id=`aws codepipeline list-pipeline-executions --pipeline-name ${CODEPIPELINE_NAME}| jq -r '.pipelineExecutionSummaries[] | select(.status == "InProgress").pipelineExecutionId' | tail -n 1` 
      - echo "current execution id is ${exec_id}"
      # Get ECR repo name from DynamoDB
      - ecr_repo=`aws dynamodb get-item --table-name ${DYNAMODB_TABLE_NAME} --key '{"execution_id":{"S":"'${exec_id}'"}}' --query Item.ecr_repo.S --output text`
      - echo "ecr repo is ${ecr_repo}"
      - image_name=${ecr_repo#*/}
      # Login to aws ECR
      - echo "logging in to AWS ECR"
      - aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin aws-account.dkr.ecr.us-east-1.amazonaws.com
      - echo "done ..."
      # 1. Get the last numerical version number before LATEST
      - LAST_VERSION=`aws ecr describe-images --repository-name "ecr-${IMAGE_DES}/${image_name}" --region us-east-1 --query 'imageDetails[].[imageTags[]]' --output text | sort -V | tail -n 2`
      - LAST_VERSION=$(echo "$LAST_VERSION" | awk 'NR==1')
      - |
        if [[ $LAST_VERSION =~ [[:space:]] ]]; then
          # 3. Push the new image to ECR (ECR auto update LATEST tag)
          echo "LAST_VERSION:0.1"
          docker pull aws-account.dkr.ecr.us-east-1.amazonaws.com/ecr-${IMAGE_SRC}/${image_name}
          docker tag aws-account.dkr.ecr.us-east-1.amazonaws.com/ecr-${IMAGE_SRC}/${image_name} aws-account.dkr.ecr.us-east-1.amazonaws.com/ecr-${IMAGE_DES}/${image_name}
          docker push aws-account.dkr.ecr.us-east-1.amazonaws.com/ecr-${IMAGE_DES}/${image_name}
        else
          MAJOR_NUM="${LAST_VERSION%%.*}"
          VERSION_NUM="${LAST_VERSION#*.}"
          ((VERSION_NUM++))
          LAST_VERSION="${MAJOR_NUM}.${VERSION_NUM}"
          echo "LAST_VERSION:${LAST_VERSION}"
          # 2. Retag numerical version number to current LATEST
          echo "retagging latest image on ECR"
          MANIFEST=$(aws ecr batch-get-image --region us-east-1 --repository-name "ecr-${IMAGE_DES}/${image_name}" --image-ids imageTag=latest --output text --query images[].imageManifest)
          aws ecr put-image --region us-east-1 --repository-name "ecr-${IMAGE_DES}/${image_name}" --image-tag ${LAST_VERSION} --image-manifest "$MANIFEST"
          echo "done ..."
          # 3. Push the new image to ECR (ECR auto update LATEST tag)
          docker pull aws-account.dkr.ecr.us-east-1.amazonaws.com/ecr-${IMAGE_SRC}/${image_name}
          docker tag aws-account.dkr.ecr.us-east-1.amazonaws.com/ecr-${IMAGE_SRC}/${image_name} aws-account.dkr.ecr.us-east-1.amazonaws.com/ecr-${IMAGE_DES}/${image_name}
          docker push aws-account.dkr.ecr.us-east-1.amazonaws.com/ecr-${IMAGE_DES}/${image_name}
        fi

Who do I talk to

aws_codepipeline-image-cicd's People

Contributors

jeffreywangzhi avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.