Skip to content

AWS CodePipeline

To set up automated migration using AWS CodePipeline, follow these steps:

Deploy CloudFormation Template

Use the provided CloudFormation template (code-pipeline.yml) to create the pipeline infrastructure.

Configure Pipeline Stages

The pipeline consists of the following stages:

  1. Source Stage
  • Retrieves code from the specified AWS CodeCommit repository
  1. Approval Stage
  • Pauses pipeline for manual review of changes
  • Requires explicit approval to proceed
  1. Build Stage
  • Runs CodeBuild project
  • Executes generate and migrate scripts
  • Uses specified profile from configuration

Pipeline Configuration

The pipeline uses env.json to store:

  • AWS profiles
  • Source environment settings
  • Destination environment settings

TIP

Manual triggering is required by releasing changes and providing the desired profile name.

Sample CloudFormation Template

The following is a CloudFormation template for the pipeline:

yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: "AWS CodePipeline for Amazon Connect Migration"

Parameters:
  RepositoryName:
    Type: String
    Default: ""
    Description: "Name of the CodeCommit repository"
  BranchName:
    Type: String
    Default: "main"
    Description: "Name of the branch to trigger the pipeline"
  BitbucketConnectionArn:
    Type: String
    Default: ""
    Description: "ARN of the AWS CodeStar connection for Bitbucket"
  BitbucketRepositoryId:
    Type: String
    Default: ""
    Description: "Full repository ID in the format 'username/repository'"
  GitHubOwner:
    Type: String
    Default: ""
    Description: "GitHub username or organization"
  GitHubRepository:
    Type: String
    Default: ""
    Description: "Name of the GitHub repository"
  GitHubOAuthToken:
    Type: String
    Default: ""
    NoEcho: true
    Description: "Personal access token for GitHub"

Conditions:
  UseCodeCommit: !Not [!Equals [!Ref RepositoryName, ""]]
  UseBitbucket: !And
    - !Not [!Equals [!Ref BitbucketConnectionArn, ""]]
    - !Not [!Equals [!Ref BitbucketRepositoryId, ""]]

Resources:
  CodePipelineRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: !Sub "${AWS::StackName}-CodePipelineRole"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
            Action: "sts:AssumeRole"
          - Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
            Action: "sts:AssumeRole"
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-CodePipelinePermissions"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "codecommit:CancelUploadArchive"
                  - "codecommit:GetBranch"
                  - "codecommit:GetCommit"
                  - "codecommit:GetUploadArchiveStatus"
                  - "codecommit:UploadArchive"
                Resource:
                  - !Join
                    - ":"
                    - - "arn"
                      - "aws"
                      - "codecommit"
                      - !Ref AWS::Region
                      - !Ref AWS::AccountId
                      - !Ref RepositoryName
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:GetBucketVersioning
                  - s3:PutObjectAcl
                  - s3:PutObject
                Resource: !Sub "${ArtifactStoreBucket.Arn}/*"
              - Effect: Allow
                Action:
                  - "codebuild:BatchGetBuilds"
                  - "codebuild:StartBuild"
                Resource: !GetAtt CodeBuildProject.Arn

  CodeBuildRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: !Sub "${AWS::StackName}-CodeBuildRole"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
            Action: "sts:AssumeRole"
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-CodeBuildPermissions"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "logs:CreateLogGroup"
                  - "logs:CreateLogStream"
                  - "logs:PutLogEvents"
                Resource:
                  - !Join
                    - ":"
                    - - "arn"
                      - "aws"
                      - "logs"
                      - !Ref "AWS::Region"
                      - !Ref "AWS::AccountId"
                      - "log-group"
                      - !Sub "/aws/codebuild/${AWS::StackName}-AmazonConnectMigrationBuild"
                      - "*"

              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:GetBucketVersioning
                  - s3:PutObjectAcl
                  - s3:PutObject
                  - s3:ListBucket
                Resource: !Sub "${ArtifactStoreBucket.Arn}/*"

  CodeBuildProject:
    Type: "AWS::CodeBuild::Project"
    Properties:
      Name: !Sub "${AWS::StackName}-AmazonConnectMigrationBuild"
      Description: "CodeBuild project for Amazon Connect Migration"
      ServiceRole: !GetAtt CodeBuildRole.Arn
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        Type: LINUX_CONTAINER
        ComputeType: BUILD_GENERAL1_SMALL
        Image: "aws/codebuild/standard:5.0"
      Source:
        Type: CODEPIPELINE
        BuildSpec: |
          version: 0.2
          phases:
            install:
              runtime-versions:
                nodejs: 20
              commands:
                - npm install
            build:
              commands:
                - |
                  if [ -n "$PROFILE" ]; then
                    npm run generate -- --profile=$PROFILE
                    npm run migrate -- --profile=$PROFILE
                  else
                    npm run generate
                    npm run migrate
                  fi
      TimeoutInMinutes: 10

  Pipeline:
    Type: "AWS::CodePipeline::Pipeline"
    Properties:
      Name: !Sub "${AWS::StackName}-AWSConnectMigrationPipeline"
      PipelineType: V2
      RoleArn: !GetAtt CodePipelineRole.Arn
      ArtifactStore:
        Type: S3
        Location: !Ref ArtifactStoreBucket

      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: !If
                  - UseCodeCommit
                  - AWS
                  - ThirdParty
                Provider: !If
                  - UseCodeCommit
                  - CodeCommit
                  - !If
                    - UseBitbucket
                    - CodeStarSourceConnection
                    - GitHub
                Version: "1"
              Configuration: !If
                - UseCodeCommit
                - RepositoryName: !Ref RepositoryName
                  BranchName: !Ref BranchName
                - !If
                  - UseBitbucket
                  - ConnectionArn: !Ref BitbucketConnectionArn
                    FullRepositoryId: !Ref BitbucketRepositoryId
                    BranchName: !Ref BranchName
                  - Owner: !Ref GitHubOwner
                    Repo: !Ref GitHubRepository
                    Branch: !Ref BranchName
                    OAuthToken: !Ref GitHubOAuthToken
              OutputArtifacts:
                - Name: SourceOutput
              RunOrder: 1
        - Name: ManualApproval
          Actions:
            - Name: ApprovalAction
              ActionTypeId:
                Category: Approval
                Owner: AWS
                Provider: Manual
                Version: "1"
              RunOrder: 1
        - Name: Build
          Actions:
            - Name: BuildAction
              ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: "1"
              Configuration:
                ProjectName: !Ref CodeBuildProject
                EnvironmentVariables: |
                  [
                    {
                      "name": "PROFILE",
                      "type": "PLAINTEXT",
                      "value": "#{variables.ProfileName}"
                    }
                  ]
              InputArtifacts:
                - Name: SourceOutput
              OutputArtifacts:
                - Name: BuildOutput
      Variables:
        - Name: ProfileName
          Description: "Profile name from env.json (optional)"
          DefaultValue: "test"

  ArtifactStoreBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      VersioningConfiguration:
        Status: Enabled