0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Django+Nginx] CloudFormationを使ってECS FargateをBlue/GreenデプロイするCodePipelineを構築しよう!

Last updated at Posted at 2024-02-01

概要

ECS FargateのBlue/Greenデプロイを自動化するCodePipelineの構築方法について解説します

前提

  • リージョンはap-northeast-1を使用
  • VPC、ECS、RDS(Postgres)、ALBを作成済み
  • ECRリポジトリ内にNginxとDjangoのDocker imageがあること
  • Blue/Greenデプロイ用のターゲットグループとリスナーを設定済み
  • DjangoのプロジェクトをECSへデプロイ済み
  • 対象プロジェクトのGitHubリポジトリを作成済み
  • AWS CodeStarと接続済み

ディレクトリ構成

tree
・
├── backend # バックエンドのソースコード
├── codebuild
│   ├── buildspec_django.yml
│   └── buildspec_nginx.yml
├── codedeploy
│   └── appspec.yml
├── containers
│   ├── django
│   │   ├── Dockerfile.prd
│   │   └── entrypoint.prd.sh
│   └── nginx
│       ├── Dockerfile.prd
│       └── nginx.prd.conf
└── ecs
    └── taskdef.json

CodePipelineの作成

codepipeline-for-backend.yml
AWSTemplateFormatVersion: 2010-09-09
Description: "CodePipeline Stack For Backend (ECS Fargate) Stack"

# -------------------------------------
# Metadata
# -------------------------------------
Metadata:
  AWS::CloudFormation::Interface:
    # パラメータの並び順
    ParameterGroups:
      - Label:
          default: "Project Configuration"
        Parameters:
          - ProjectName
          - Environment
      - Label:
          default: "GitHub Configuration"
        Parameters:
          - BackEndRepositoryName
          - SourceBranchName
          - DjangoDockerfilePath
          - NginxDockerfilePath
          - TaskDefinitionTemplatePath
          - AppSpecTemplatePath
      - Label:
          default: "CodeBuild Configuration"
        Parameters:
          - ECRBackEndDjangoRepositoryName
          - ECRBackEndNginxRepositoryName
      - Label:
          default: "CodeDeploy Configuration"
        Parameters:
          - CodeDeployApplicationName
          - CodeDeployDeploymentGroupName
          - CodeDeployDeploymentConfigName
          - ECSClusterName
          - ECSServiceName
          - ALBTargetGroupBlueName
          - ALBTargetGroupGreenName
          - ALBProductionListenerArn
          - ALBTestListenerArn
      - Label:
          default: "CodePipeline Configuration"
        Parameters:
          - CodeStarConnectionArn

# -------------------------------------
# Input parameters
# -------------------------------------
Parameters:
  ProjectName:
    Description: "Enter the project name. (ex: my-project)"
    Type: String
    MinLength: 1
    ConstraintDescription: "ProjectName must be enter."
    Default: my-project
  Environment:
    Description: "Select the environment."
    Type: String
    AllowedValues:
      - dev
      - stg
      - prd
    ConstraintDescription: "Environment must be select."
  BackEndRepositoryName:
    Description: "Enter the target GitHub backend full repository name. (ex: shun198/cloud-formation-playground)"
    Type: String
    Default: shun198/cloud-formation-playground
  SourceBranchName:
    Description: "Enter the source branch name in GitHub backend repository. (ex: develop or main)"
    Type: String
    AllowedValues:
      - develop
      - main
  DjangoDockerfilePath:
    Description: "Enter the Django Dockerfile path in GitHub backend repository. (ex: containers/django/Dockerfile.prd)"
    Type: String
  NginxDockerfilePath:
    Description: "Enter the Nginx Dockerfile path in GitHub backend repository. (ex: containers/nginx/Dockerfile.prd)"
    Type: String
  TaskDefinitionTemplatePath:
    Description: "Enter the ECS Task Definition template path in GitHub backend repository. (ex: ecs/taskdef.json)"
    Type: String
  AppSpecTemplatePath:
    Description: "Enter the Codedeploy Appspec template path in GitHub backend repository. (ex: codedeploy/appspec.yml)"
    Type: String
  ECRBackEndDjangoRepositoryName:
    Description: "Enter the ECR backend application repository name. (ex: my-project/dev/back/django)"
    Type: String
  ECRBackEndNginxRepositoryName:
    Description: "Enter the ECR backend webserver repository name. (ex: my-project/dev/back/nginx)"
    Type: String
  CodeDeployApplicationName:
    Description: "Enter the CodeDeploy application name. (ex: my-project-dev-cdapp)"
    Type: String
  CodeDeployDeploymentGroupName:
    Description: "Enter the CodeDeploy deployment group name. (ex: my-project-dev-cdg)"
    Type: String
  CodeDeployDeploymentConfigName:
    Description: "Enter the CodeDeploy deployment config name."
    Type: String
    AllowedValues:
      - CodeDeployDefault.ECSLinear10PercentEvery1Minutes
      - CodeDeployDefault.ECSLinear10PercentEvery3Minutes
      - CodeDeployDefault.ECSCanary10Percent5Minutes
      - CodeDeployDefault.ECSCanary10Percent15Minutes
      - CodeDeployDefault.ECSAllAtOnce
  ECSClusterName:
    Description: "Enter the ECS cluster name. (ex: my-project-dev-cluster)"
    Type: String
  ECSServiceName:
    Description: "Enter the ECS cluster name. (ex: my-project-dev-back-service)"
    Type: String
  ALBTargetGroupBlueName:
    Description: "Enter the ALB Target Group Name for Blue / Green Deployment. (ex: my-project-dev-tg-blue)"
    Type: String
  ALBTargetGroupGreenName:
    Description: "Enter the ALB Target Group Name for Blue / Green Deployment. (ex: my-project-dev-tg-green)"
    Type: String
  ALBProductionListenerArn:
    Description: "Enter the ALB Production Listener ARN for Blue / Green Deployment."
    Type: String
  ALBTestListenerArn:
    Description: "Enter the ALB Test Listener ARN for Blue / Green Deployment."
    Type: String
  CodeStarConnectionArn:
    Description: "Enter the CodeStar connection ARN. (ex: arn:aws:codestar-connections:<aws_region>:<aws_account_id>:connection/<connection_id>)"
    Type: String

# -------------------------------------
# Resources
# -------------------------------------
Resources:
  # -------------------------------------
  # IAM
  # -------------------------------------
  # CodeBuild 用の IAM Policy
  CodeBuildServiceRolePolicy:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub CodeBuildServiceRolePolicyForBackEnd-${ProjectName}-${Environment}
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Resource:
              - !Sub
                - arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildProjectName}
                - { CodeBuildProjectName: !Sub "${ProjectName}-${Environment}-back-cbpj" }
              - !Sub
                - arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildProjectName}:*
                - { CodeBuildProjectName: !Sub "${ProjectName}-${Environment}-back-cbpj" }
          - Effect: Allow
            Action:
              - s3:GetBucketAcl
              - s3:GetBucketLocation
            Resource: !Sub arn:aws:s3:::${ArtifactBucket}*
          - Effect: Allow
            Action:
              - s3:PutObject
              - s3:GetObject
              - s3:GetObjectVersion
            Resource: !Sub arn:aws:s3:::${ArtifactBucket}/*
          - Effect: Allow
            Action:
              - codebuild:CreateReportGroup
              - codebuild:CreateReport
              - codebuild:UpdateReport
              - codebuild:BatchPutTestCases
              - codebuild:BatchPutCodeCoverages
            Resource: !Sub
              - arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/${CodeBuildProjectName}*
              - { CodeBuildProjectName: !Sub "${ProjectName}-${Environment}-back-cbpj" }
          - Effect: Allow
            Action:
              - codebuild:StartBuild
              - codebuild:StopBuild
              - codebuild:RetryBuild
            Resource: !Sub
              - arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/${CodeBuildProjectName}
              - { CodeBuildProjectName: !Sub "${ProjectName}-${Environment}-back-cbpj" }
          - Effect: Allow
            Action:
              - ecr:GetAuthorizationToken
              - ecr:BatchCheckLayerAvailability
              - ecr:GetDownloadUrlForLayer
              - ecr:GetRepositoryPolicy
              - ecr:DescribeRepositories
              - ecr:ListImages
              - ecr:DescribeImages
              - ecr:BatchGetImage
              - ecr:GetLifecyclePolicy
              - ecr:GetLifecyclePolicyPreview
              - ecr:ListTagsForResource
              - ecr:DescribeImageScanFindings
              - ecr:InitiateLayerUpload
              - ecr:UploadLayerPart
              - ecr:CompleteLayerUpload
              - ecr:PutImage
            Resource: "*"

  # CodeBuild に適用する IAM Role
  CodeBuildServiceRole:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub CodeBuildServiceRoleForBackEnd-${ProjectName}-${Environment}
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
            Action: sts:AssumeRole
      Path: /service-role/
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
        - !Ref CodeBuildServiceRolePolicy

  # CodeDeploy Blue/Green Deployment 用 IAM Role
  CodeDeployServiceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub CodeDeployServiceRoleForBackEnd-${ProjectName}-${Environment}
      Path: /service-role/
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: codedeploy.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AWSCodeDeployRoleForECS

  # CodePipeline 用の IAM Policy
  CodePipelineServiceRolePolicy:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub CodePipelineServiceRolePolicyForBackEnd-${ProjectName}-${Environment}
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          # アクセス許可はデプロイ対象リソースに応じて変更する
          - Effect: Allow
            Action:
              - iam:PassRole
            Condition:
              StringEqualsIfExists:
                iam:PassedToService:
                  - ecs-tasks.amazonaws.com
            Resource: "*"
          - Effect: Allow
            Action:
              - s3:*
            Resource:
              - !Sub arn:aws:s3:::${ArtifactBucket}*
          - Effect: Allow
            Action:
              - codedeploy:CreateDeployment
              - codedeploy:GetApplication
              - codedeploy:GetApplicationRevision
              - codedeploy:GetDeployment
              - codedeploy:GetDeploymentConfig
              - codedeploy:RegisterApplicationRevision
            Resource: "*"
          - Effect: Allow
            Action:
              - codestar-connections:UseConnection
            Resource: "*"
          - Effect: Allow
            Action:
              - codebuild:BatchGetBuilds
              - codebuild:StartBuild
              - codebuild:BatchGetBuildBatches
              - codebuild:StartBuildBatch
            Resource: "*"
          - Effect: Allow
            Action:
              - ecr:DescribeImages
              - ecs:RegisterTaskDefinition
            Resource: "*"
          - Effect: Allow
            Action:
              - sns:Publish
            Resource: "*"

  # CodePipeline に適用する IAM Role
  CodePipelineServiceRole:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub CodePipelineServiceRoleForBackEnd-${ProjectName}-${Environment}
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
            Action: sts:AssumeRole
      Path: /service-role/
      ManagedPolicyArns:
        - !Ref CodePipelineServiceRolePolicy

  # -------------------------------------
  # S3 Bucket
  # -------------------------------------
  # For CodePipeline Artifact
  ArtifactBucket:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${ProjectName}-${Environment}-back-artifact
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

  # -------------------------------------
  # CodeBuild
  # -------------------------------------
  CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: !Sub ${ProjectName}-${Environment}-back-cbpj
      ServiceRole: !GetAtt CodeBuildServiceRole.Arn
      BuildBatchConfig:
        ServiceRole: !GetAtt CodeBuildServiceRole.Arn
      Artifacts:
        Type: CODEPIPELINE
      Source:
        Type: CODEPIPELINE
        BuildSpec: |
          version: 0.2
          batch:
            build-list:
              - identifier: BuildBackEndDjangoArtifact
                buildspec: codebuild/buildspec_django.yml
              - identifier: BuildBackEndNginxArtifact
                buildspec: codebuild/buildspec_nginx.yml
      Environment:
        PrivilegedMode: true
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0
        Type: LINUX_CONTAINER
        EnvironmentVariables:
          - Name: AWS_DEFAULT_ACCOUNT
            Value: !Ref AWS::AccountId
          - Name: AWS_DEFAULT_REGION
            Value: !Ref AWS::Region
          - Name: DOCKER_BUILDKIT
            Value: 1
          - Name: DOCKERHUB_TOKEN
            Type: PARAMETER_STORE
            Value: !Sub /${ProjectName}/common/DOCKERHUB_TOKEN
          - Name: DOCKERHUB_USER
            Type: PARAMETER_STORE
            Value: !Sub /${ProjectName}/common/DOCKERHUB_USER
          - Name: ECR_DJANGO_REPOSITORY_URI
            Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${ECRBackEndDjangoRepositoryName}
          - Name: ECR_NGINX_REPOSITORY_URI
            Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${ECRBackEndNginxRepositoryName}
          - Name: ENVIRONMENT
            Value: !Ref Environment
          - Name: DJANGO_DOCKERFILE_PATH
            Value: !Ref DjangoDockerfilePath
          - Name: NGINX_DOCKERFILE_PATH
            Value: !Ref NginxDockerfilePath
          - Name: PROJECT_NAME
            Value: !Ref ProjectName
  # -------------------------------------
  # CodeDeploy
  # -------------------------------------
  CodeDeployApplication:
    Type: AWS::CodeDeploy::Application
    Properties:
      ApplicationName: !Ref CodeDeployApplicationName
      ComputePlatform: ECS
      Tags:
        - Key: ProjectName
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment
  CodeDeployDeploymentGroup:
    Type: AWS::CodeDeploy::DeploymentGroup
    Properties:
      ApplicationName: !Ref CodeDeployApplication
      AutoRollbackConfiguration:
        Enabled: true
        Events:
          - DEPLOYMENT_FAILURE
      BlueGreenDeploymentConfiguration:
        DeploymentReadyOption:
          ActionOnTimeout: CONTINUE_DEPLOYMENT
        TerminateBlueInstancesOnDeploymentSuccess:
          Action: TERMINATE
          TerminationWaitTimeInMinutes: 30
      DeploymentGroupName: !Ref CodeDeployDeploymentGroupName
      ServiceRoleArn: !GetAtt CodeDeployServiceRole.Arn
      ECSServices:
        - ClusterName: !Ref ECSClusterName
          ServiceName: !Ref ECSServiceName
      LoadBalancerInfo:
        TargetGroupPairInfoList:
          - ProdTrafficRoute:
              ListenerArns:
                - !Ref ALBProductionListenerArn
            TargetGroups:
              - Name: !Ref ALBTargetGroupBlueName
              - Name: !Ref ALBTargetGroupGreenName
            TestTrafficRoute:
              ListenerArns:
                - !Ref ALBTestListenerArn
      DeploymentStyle:
        DeploymentOption: WITH_TRAFFIC_CONTROL
        DeploymentType: BLUE_GREEN
      DeploymentConfigName: !Ref CodeDeployDeploymentConfigName
      Tags:
        - Key: ProjectName
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment

  # -------------------------------------
  # CodePipeline
  # -------------------------------------
  CodePipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !GetAtt CodePipelineServiceRole.Arn
      Name: !Sub ${ProjectName}-${Environment}-back-pipeline
      ArtifactStore:
        Type: S3
        Location: !Ref ArtifactBucket
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: CodeStarSourceConnection
                Version: 1
              Configuration:
                FullRepositoryId: !Ref BackEndRepositoryName
                ConnectionArn: !Ref CodeStarConnectionArn
                BranchName: !Ref SourceBranchName
                DetectChanges: true
              OutputArtifacts:
                - Name: SourceArtifact
              RunOrder: 1
        - Name: Build
          Actions:
            - Name: BuildAction
              ActionTypeId:
                Category: Build
                Owner: AWS
                Version: 1
                Provider: CodeBuild
              Configuration:
                ProjectName: !Ref CodeBuildProject
                PrimarySource: SourceArtifact
                BatchEnabled: true
              RunOrder: 1
              InputArtifacts:
                - Name: SourceArtifact
              OutputArtifacts:
                - Name: BuildBackEndDjangoArtifact
                - Name: BuildBackEndNginxArtifact
        - Name: Deploy
          Actions:
            - Name: DeployAction
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: 1
                Provider: CodeDeployToECS
              Configuration:
                AppSpecTemplateArtifact: SourceArtifact
                AppSpecTemplatePath: !Ref AppSpecTemplatePath
                TaskDefinitionTemplateArtifact: SourceArtifact
                TaskDefinitionTemplatePath: !Ref TaskDefinitionTemplatePath
                ApplicationName: !Ref CodeDeployApplicationName
                DeploymentGroupName: !Ref CodeDeployDeploymentGroupName
                Image1ArtifactName: BuildBackEndDjangoArtifact
                Image1ContainerName: DJANGO_IMAGE_NAME
                Image2ArtifactName: BuildBackEndNginxArtifact
                Image2ContainerName: NGINX_IMAGE_NAME
              RunOrder: 1
              InputArtifacts:
                - Name: SourceArtifact
                - Name: BuildBackEndDjangoArtifact
                - Name: BuildBackEndNginxArtifact
              Region: !Ref AWS::Region

# -------------------------------------
# Output parameters
# -------------------------------------
Outputs:
  CodePipelineLogicalID:
    Value: !Ref CodePipeline
  CodeBuildServiceRoleArn:
    Value: !GetAtt CodeBuildServiceRole.Arn
  CodeBuildProjectArn:
    Value: !GetAtt CodeBuildProject.Arn
  CodeBuildProjectName:
    Value: !Ref CodeBuildProject
  CodeDeployDeploymentGroupArn:
    Value: !Ref CodeDeployDeploymentGroup
  ArtifactBucketArn:
    Value: !GetAtt ArtifactBucket.Arn
  ArtifactBucketName:
    Value: !Ref ArtifactBucket

一つずつ解説していきます

Artifactの設定

今回はCodePipelineを実行する際に

  • BuildArtifact
  • SourceArtifact

の2種類を使用し、Artifactを格納するためのS3バケットを作成します
今回はパブリックアクセスをプロックするよう設定します

  # -------------------------------------
  # S3 Bucket
  # -------------------------------------
  # For CodePipeline Artifact
  ArtifactBucket:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${ProjectName}-${Environment}-back-artifact
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

バケットを作成し、CodePipelineを実行すると以下のようにArtifactが格納されます

スクリーンショット 2024-01-31 21.41.40.png

IAM

CodeBuild

CodeBuild実行用のIAMロールとポリシーを作成します
パラメータストアの値を取得できるAmazonSSMManagedInstanceCoreと以下のことができるカスタムポリシーを今回作成するIAMロールに付与します

  • CodeBuildの実行、停止、再実行、レポート関連の操作
  • S3に格納されたArtifactの操作
  • CloudWatchを有効化してBuild時のログを出力
  • ECRからImageを取得
  # -------------------------------------
  # IAM
  # -------------------------------------
  # CodeBuild 用の IAM Policy
  CodeBuildServiceRolePolicy:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub CodeBuildServiceRolePolicyForBackEnd-${ProjectName}-${Environment}
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Resource:
              - !Sub
                - arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildProjectName}
                - { CodeBuildProjectName: !Sub "${ProjectName}-${Environment}-back-cbpj" }
              - !Sub
                - arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildProjectName}:*
                - { CodeBuildProjectName: !Sub "${ProjectName}-${Environment}-back-cbpj" }
          - Effect: Allow
            Action:
              - s3:GetBucketAcl
              - s3:GetBucketLocation
            Resource: !Sub arn:aws:s3:::${ArtifactBucket}*
          - Effect: Allow
            Action:
              - s3:PutObject
              - s3:GetObject
              - s3:GetObjectVersion
            Resource: !Sub arn:aws:s3:::${ArtifactBucket}/*
          - Effect: Allow
            Action:
              - codebuild:CreateReportGroup
              - codebuild:CreateReport
              - codebuild:UpdateReport
              - codebuild:BatchPutTestCases
              - codebuild:BatchPutCodeCoverages
            Resource: !Sub
              - arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/${CodeBuildProjectName}*
              - { CodeBuildProjectName: !Sub "${ProjectName}-${Environment}-back-cbpj" }
          - Effect: Allow
            Action:
              - codebuild:StartBuild
              - codebuild:StopBuild
              - codebuild:RetryBuild
            Resource: !Sub
              - arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/${CodeBuildProjectName}
              - { CodeBuildProjectName: !Sub "${ProjectName}-${Environment}-back-cbpj" }
          - Effect: Allow
            Action:
              - ecr:GetAuthorizationToken
              - ecr:BatchCheckLayerAvailability
              - ecr:GetDownloadUrlForLayer
              - ecr:GetRepositoryPolicy
              - ecr:DescribeRepositories
              - ecr:ListImages
              - ecr:DescribeImages
              - ecr:BatchGetImage
              - ecr:GetLifecyclePolicy
              - ecr:GetLifecyclePolicyPreview
              - ecr:ListTagsForResource
              - ecr:DescribeImageScanFindings
              - ecr:InitiateLayerUpload
              - ecr:UploadLayerPart
              - ecr:CompleteLayerUpload
              - ecr:PutImage
            Resource: "*"

  # CodeBuild に適用する IAM Role
  CodeBuildServiceRole:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub CodeBuildServiceRoleForBackEnd-${ProjectName}-${Environment}
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
            Action: sts:AssumeRole
      Path: /service-role/
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
        - !Ref CodeBuildServiceRolePolicy

CodeDeploy

AWSCodeDeployRoleForECSのポリシーが付与されたCodeDeployのロールを作成します

  # CodeDeploy Blue/Green Deployment 用 IAM Role
  CodeDeployServiceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub CodeDeployServiceRoleForBackEnd-${ProjectName}-${Environment}
      Path: /service-role/
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: codedeploy.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AWSCodeDeployRoleForECS

CodePipeline

CodePipeline実行用のIAMロールとポリシーを作成します
以下のことができるカスタムポリシーを今回作成するIAMロールに付与します

  • S3に格納されたArtifactの操作
  • CodeStarとの接続
  • CodeBuildのビルドとバッチビルドの開始と情報の取得
  • CodeDeployのアプリケーションやデプロイグループの情報の取得、デプロイの作成、デプロイ設定の作成など
  • ECSの新しいタスク定義の登録
  • ECR内のイメージに関するメタデータ(イメージサイズ、イメージタグ、作成日)の取得

SNS通知の実装については別記事で解説したいと思います

  # CodePipeline 用の IAM Policy
  CodePipelineServiceRolePolicy:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: !Sub CodePipelineServiceRolePolicyForBackEnd-${ProjectName}-${Environment}
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          # アクセス許可はデプロイ対象リソースに応じて変更する
          - Effect: Allow
            Action:
              - iam:PassRole
            Condition:
              StringEqualsIfExists:
                iam:PassedToService:
                  - ecs-tasks.amazonaws.com
            Resource: "*"
          - Effect: Allow
            Action:
              - s3:*
            Resource:
              - !Sub arn:aws:s3:::${ArtifactBucket}*
          - Effect: Allow
            Action:
              - codedeploy:CreateDeployment
              - codedeploy:GetApplication
              - codedeploy:GetApplicationRevision
              - codedeploy:GetDeployment
              - codedeploy:GetDeploymentConfig
              - codedeploy:RegisterApplicationRevision
            Resource: "*"
          - Effect: Allow
            Action:
              - codestar-connections:UseConnection
            Resource: "*"
          - Effect: Allow
            Action:
              - codebuild:BatchGetBuilds
              - codebuild:StartBuild
              - codebuild:BatchGetBuildBatches
              - codebuild:StartBuildBatch
            Resource: "*"
          - Effect: Allow
            Action:
              - ecr:DescribeImages
              - ecs:RegisterTaskDefinition
            Resource: "*"
          - Effect: Allow
            Action:
              - sns:Publish
            Resource: "*"

  # CodePipeline に適用する IAM Role
  CodePipelineServiceRole:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub CodePipelineServiceRoleForBackEnd-${ProjectName}-${Environment}
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
            Action: sts:AssumeRole
      Path: /service-role/
      ManagedPolicyArns:
        - !Ref CodePipelineServiceRolePolicy

CodeBuildの設定

CodeBuildプロジェクトを作成します

  # -------------------------------------
  # CodeBuild
  # -------------------------------------
  CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: !Sub ${ProjectName}-${Environment}-back-cbpj
      ServiceRole: !GetAtt CodeBuildServiceRole.Arn
      BuildBatchConfig:
        ServiceRole: !GetAtt CodeBuildServiceRole.Arn
      Artifacts:
        Type: CODEPIPELINE
      Source:
        Type: CODEPIPELINE
        BuildSpec: |
          version: 0.2
          batch:
            build-list:
              - identifier: BuildBackEndDjangoArtifact
                buildspec: codebuild/buildspec_django.yml
              - identifier: BuildBackEndNginxArtifact
                buildspec: codebuild/buildspec_nginx.yml
      Environment:
        PrivilegedMode: true
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0
        Type: LINUX_CONTAINER
        EnvironmentVariables:
          - Name: AWS_DEFAULT_ACCOUNT
            Value: !Ref AWS::AccountId
          - Name: AWS_DEFAULT_REGION
            Value: !Ref AWS::Region
          - Name: DOCKER_BUILDKIT
            Value: 1
          - Name: DOCKERHUB_TOKEN
            Type: PARAMETER_STORE
            Value: !Sub /${ProjectName}/common/DOCKERHUB_TOKEN
          - Name: DOCKERHUB_USER
            Type: PARAMETER_STORE
            Value: !Sub /${ProjectName}/common/DOCKERHUB_USER
          - Name: ECR_DJANGO_REPOSITORY_URI
            Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${ECRBackEndDjangoRepositoryName}
          - Name: ECR_NGINX_REPOSITORY_URI
            Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${ECRBackEndNginxRepositoryName}
          - Name: ENVIRONMENT
            Value: !Ref Environment
          - Name: DJANGO_DOCKERFILE_PATH
            Value: !Ref DjangoDockerfilePath
          - Name: NGINX_DOCKERFILE_PATH
            Value: !Ref NginxDockerfilePath
          - Name: PROJECT_NAME
            Value: !Ref ProjectName

プロパティ

プロパティの設定では

  • サービスロール
  • バッチビルド用ロール

を設定します
また、今回はDjangoとNginxの2種類のbuildspecファイルを使ってbuildをするので以下のようにbuild-listを指定します

  • BuildBackEndDjangoArtifact
  • BuildBackEndNginxArtifact

の詳細はCodePipelineの箇所でもう一度説明します

        BuildSpec: |
          version: 0.2
          batch:
            build-list:
              - identifier: BuildBackEndDjangoArtifact
                buildspec: codebuild/buildspec_django.yml
              - identifier: BuildBackEndNginxArtifact
                buildspec: codebuild/buildspec_nginx.yml

CodeDeployの設定

  • CodeDeployアプリケーション
  • CodeDeployデプロイグループ

を作成します

  # -------------------------------------
  # CodeDeploy
  # -------------------------------------
  CodeDeployApplication:
    Type: AWS::CodeDeploy::Application
    Properties:
      ApplicationName: !Ref CodeDeployApplicationName
      ComputePlatform: ECS
      Tags:
        - Key: ProjectName
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment
  CodeDeployDeploymentGroup:
    Type: AWS::CodeDeploy::DeploymentGroup
    Properties:
      ApplicationName: !Ref CodeDeployApplication
      AutoRollbackConfiguration:
        Enabled: true
        Events:
          - DEPLOYMENT_FAILURE
      BlueGreenDeploymentConfiguration:
        DeploymentReadyOption:
          ActionOnTimeout: CONTINUE_DEPLOYMENT
        TerminateBlueInstancesOnDeploymentSuccess:
          Action: TERMINATE
          TerminationWaitTimeInMinutes: 30
      DeploymentGroupName: !Ref CodeDeployDeploymentGroupName
      ServiceRoleArn: !GetAtt CodeDeployServiceRole.Arn
      ECSServices:
        - ClusterName: !Ref ECSClusterName
          ServiceName: !Ref ECSServiceName
      LoadBalancerInfo:
        TargetGroupPairInfoList:
          - ProdTrafficRoute:
              ListenerArns:
                - !Ref ALBProductionListenerArn
            TargetGroups:
              - Name: !Ref ALBTargetGroupBlueName
              - Name: !Ref ALBTargetGroupGreenName
            TestTrafficRoute:
              ListenerArns:
                - !Ref ALBTestListenerArn
      DeploymentStyle:
        DeploymentOption: WITH_TRAFFIC_CONTROL
        DeploymentType: BLUE_GREEN
      DeploymentConfigName: !Ref CodeDeployDeploymentConfigName
      Tags:
        - Key: ProjectName
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment

CodeDeployアプリケーション

CodeDeployアプリケーションを作成します
今回はECS FargateをデプロイするのでプラットフォームはECSにします

  CodeDeployApplication:
    Type: AWS::CodeDeploy::Application
    Properties:
      ApplicationName: !Ref CodeDeployApplicationName
      ComputePlatform: ECS
      Tags:
        - Key: ProjectName
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment

CodeDeployデプロイグループ

デプロイグループを作成します
AutoRollbackConfigurationで自動ロールバックを有効にし、DEPLOYMENT_FAILUREのイベント時に発火するよう設定します

BlueGreenDeploymentConfigurationのDeploymentReadyOptionを使ってGreen環境ができたらすぐにロードバランザーのトラフィックを変更するよう設定します

TerminateBlueInstancesOnDeploymentSuccessのオプションでBlue/Greenデプロイに成功したらBlueのインスタンスを自動で削除します
LoadBalancerInfo内に

  • 本番用とテスト用のリスナー
  • Blue用とGreen用のターゲットグループ

を設定します

DeploymentStyleのDeploymentOptionをWITH_TRAFFIC_CONTROL、DeploymentTypeをBLUE_GREENに設定します

  CodeDeployDeploymentGroup:
    Type: AWS::CodeDeploy::DeploymentGroup
    Properties:
      ApplicationName: !Ref CodeDeployApplication
      AutoRollbackConfiguration:
        Enabled: true
        Events:
          - DEPLOYMENT_FAILURE
      BlueGreenDeploymentConfiguration:
        DeploymentReadyOption:
          ActionOnTimeout: CONTINUE_DEPLOYMENT
        TerminateBlueInstancesOnDeploymentSuccess:
          Action: TERMINATE
          TerminationWaitTimeInMinutes: 30
      DeploymentGroupName: !Ref CodeDeployDeploymentGroupName
      ServiceRoleArn: !GetAtt CodeDeployServiceRole.Arn
      ECSServices:
        - ClusterName: !Ref ECSClusterName
          ServiceName: !Ref ECSServiceName
      LoadBalancerInfo:
        TargetGroupPairInfoList:
          - ProdTrafficRoute:
              ListenerArns:
                - !Ref ALBProductionListenerArn
            TargetGroups:
              - Name: !Ref ALBTargetGroupBlueName
              - Name: !Ref ALBTargetGroupGreenName
            TestTrafficRoute:
              ListenerArns:
                - !Ref ALBTestListenerArn
      DeploymentStyle:
        DeploymentOption: WITH_TRAFFIC_CONTROL
        DeploymentType: BLUE_GREEN
      DeploymentConfigName: !Ref CodeDeployDeploymentConfigName
      Tags:
        - Key: ProjectName
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment

詳細は以下の通りです

CodePipelineの作成

CodePipelineを作成します
CodePipeline自体の設定に加えて

  • Source
  • Build
  • Deploy

の3ステージに分けて構築します

  CodePipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !GetAtt CodePipelineServiceRole.Arn
      Name: !Sub ${ProjectName}-${Environment}-back-pipeline
      ArtifactStore:
        Type: S3
        Location: !Ref ArtifactBucket
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: CodeStarSourceConnection
                Version: 1
              Configuration:
                FullRepositoryId: !Ref BackEndRepositoryName
                ConnectionArn: !Ref CodeStarConnectionArn
                BranchName: !Ref SourceBranchName
                DetectChanges: true
              OutputArtifacts:
                - Name: SourceArtifact
              RunOrder: 1
        - Name: Build
          Actions:
            - Name: BuildAction
              ActionTypeId:
                Category: Build
                Owner: AWS
                Version: 1
                Provider: CodeBuild
              Configuration:
                ProjectName: !Ref CodeBuildProject
                PrimarySource: SourceArtifact
                BatchEnabled: true
              RunOrder: 1
              InputArtifacts:
                - Name: SourceArtifact
              OutputArtifacts:
                - Name: BuildBackEndDjangoArtifact
                - Name: BuildBackEndNginxArtifact
        - Name: Deploy
          Actions:
            - Name: DeployAction
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: 1
                Provider: CodeDeployToECS
              Configuration:
                AppSpecTemplateArtifact: SourceArtifact
                AppSpecTemplatePath: !Ref AppSpecTemplatePath
                TaskDefinitionTemplateArtifact: SourceArtifact
                TaskDefinitionTemplatePath: !Ref TaskDefinitionTemplatePath
                ApplicationName: !Ref CodeDeployApplicationName
                DeploymentGroupName: !Ref CodeDeployDeploymentGroupName
                Image1ArtifactName: BuildBackEndDjangoArtifact
                Image1ContainerName: DJANGO_IMAGE_NAME
                Image2ArtifactName: BuildBackEndNginxArtifact
                Image2ContainerName: NGINX_IMAGE_NAME
              RunOrder: 1
              InputArtifacts:
                - Name: SourceArtifact
                - Name: BuildBackEndDjangoArtifact
                - Name: BuildBackEndNginxArtifact
              Region: !Ref AWS::Region

CodePipelineの設定

CodePipelineを作成します

  • パイプライン名
  • ロール
  • Artifactを格納するバケット

を設定します

    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !GetAtt CodePipelineServiceRole.Arn
      Name: !Sub ${ProjectName}-${Environment}-back-pipeline
      ArtifactStore:
        Type: S3
        Location: !Ref ArtifactBucket

Sourceステージ

デプロイするコードを取得するSourceステージの設定を行います
今回はAWSのCodeStarを使ってGitHubリポジトリに接続するので、ProviderはCodeStarSourceConnectionにします

Configurationの箇所に

  • リポジトリID
  • CodeStarのarn
  • ブランチ名

を指定します

OutputArtifactsにSourceArtifactを指定します
こちらはBuildステージで使用します

      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: CodeStarSourceConnection
                Version: 1
              Configuration:
                FullRepositoryId: !Ref BackEndRepositoryName
                ConnectionArn: !Ref CodeStarConnectionArn
                BranchName: !Ref SourceBranchName
                DetectChanges: true
              OutputArtifacts:
                - Name: SourceArtifact
              RunOrder: 1

Buildステージ

今回はCodeBuildを使ってBuildステージ内でDockerfileをbuildします
PrimarySourceとInputArtifactにSourceArtifactを指定することでソースコード内のDockerfileをbuildできるようにします

OutputArtifactに

  • BuildBackEndDjangoArtifact
  • BuildBackEndNginxArtifact

を指定します
こちらはこの後説明するDeployステージに使用します

        - Name: Build
          Actions:
            - Name: BuildAction
              ActionTypeId:
                Category: Build
                Owner: AWS
                Version: 1
                Provider: CodeBuild
              Configuration:
                ProjectName: !Ref CodeBuildProject
                PrimarySource: SourceArtifact
                BatchEnabled: true
              RunOrder: 1
              InputArtifacts:
                - Name: SourceArtifact
              OutputArtifacts:
                - Name: BuildBackEndDjangoArtifact
                - Name: BuildBackEndNginxArtifact

Deployステージ

今回はCodeDeployを使ってDeployステージ内でbuildしたDockerfileをECS FargateへBlue/Greenデプロイします

Configurationの箇所で

  • appspec
    • アーティファクト(SourceArtifact)
    • appspec.ymlのパス
  • タスク定義
    • アーティファクト(SourceArtifact)
    • taskdef.jsonのパス
  • CodeDeploy
    • アプリケーション名
    • デプロイグループ
  • Dockerイメージのアーティファクト
    • Django
      • アーティファクト名
      • Dockerfileのパス
    • Nginx
      • アーティファクト名
      • Dockerfileのパス
  • InputArtifact
    • SourceArtifact
    • BuildBackEndDjangoArtifact
    • BuildBackEndNginxArtifact

を設定します

        - Name: Deploy
          Actions:
            - Name: DeployAction
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: 1
                Provider: CodeDeployToECS
              Configuration:
                AppSpecTemplateArtifact: SourceArtifact
                AppSpecTemplatePath: !Ref AppSpecTemplatePath
                TaskDefinitionTemplateArtifact: SourceArtifact
                TaskDefinitionTemplatePath: !Ref TaskDefinitionTemplatePath
                ApplicationName: !Ref CodeDeployApplicationName
                DeploymentGroupName: !Ref CodeDeployDeploymentGroupName
                Image1ArtifactName: BuildBackEndDjangoArtifact
                Image1ContainerName: DJANGO_IMAGE_NAME
                Image2ArtifactName: BuildBackEndNginxArtifact
                Image2ContainerName: NGINX_IMAGE_NAME
              RunOrder: 1
              InputArtifacts:
                - Name: SourceArtifact
                - Name: BuildBackEndDjangoArtifact
                - Name: BuildBackEndNginxArtifact
              Region: !Ref AWS::Region

buildspecの作成

Djangoのbuildspec

今回はcodebuildフォルダ配下にymlファイルを作成します
buildspecのphaseは

  • pre_build
  • build
  • post_build

の3種類に分類されるので1つずつ説明します

pre_build

Dockerfileをbuildする前にECRへログインするフェーズです
ログインする際はCodeBuildで設定した

  • DOCKERHUB_USER
  • DOCKERHUB_TOKEN

の環境変数を使ってECRにログインします
また、ビルドの解決済みソースバージョンの識別子の前から7文字をIMAGE_TAGの変数に代入します

image_tag.png

build

DJANGO_DOCKERFILE_PATH内にあるDockerfileをbuildし、タグ付けします

post_build

buildが完了したDockerfileをECRへpushし、imageDetail.jsonに書き込み処理を行います

codebuild/buildspec_django.yml
version: 0.2
phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_DEFAULT_ACCOUNT.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
      - echo Logging in to Docker Hub...
      - echo $DOCKERHUB_TOKEN | docker login -u $DOCKERHUB_USER --password-stdin
      - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - cd $CODEBUILD_SRC_DIR
      - docker build -f $DJANGO_DOCKERFILE_PATH -t $ECR_DJANGO_REPOSITORY_URI:$IMAGE_TAG .
      - docker tag $ECR_DJANGO_REPOSITORY_URI:$IMAGE_TAG $ECR_DJANGO_REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $ECR_DJANGO_REPOSITORY_URI:$IMAGE_TAG
      - echo Writing imageDetail.json...
      - printf '{"Version":"1.0","ImageURI":"%s"}' $ECR_DJANGO_REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
artifacts:
  files:
    - imageDetail.json

Nginxのbuildspec

Nginxのbuild_specファイルも同様に作成します

codebuild/buildspec_nginx.yml
version: 0.2
phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_DEFAULT_ACCOUNT.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
      - echo Logging in to Docker Hub...
      - echo $DOCKERHUB_TOKEN | docker login -u $DOCKERHUB_USER --password-stdin
      - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - cd $CODEBUILD_SRC_DIR
      - docker build -f $NGINX_DOCKERFILE_PATH -t $ECR_NGINX_REPOSITORY_URI:$IMAGE_TAG .
      - docker tag $ECR_NGINX_REPOSITORY_URI:$IMAGE_TAG $ECR_NGINX_REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $ECR_NGINX_REPOSITORY_URI:$IMAGE_TAG
      - echo Writing imageDetail.json...
      - printf '{"Version":"1.0","ImageURI":"%s"}' $ECR_NGINX_REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
artifacts:
  files:
    - imageDetail.json

appspecの作成

今回はcodedeployフォルダ配下にymlファイルを作成します
TaskDefinitionの箇所にを設定します
CodePipeline実行時にCodeDeployで設定したECSタスクのパスが自動的に代入されます

codedeploy/appspec.yml
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "<TASK_DEFINITION>"
        LoadBalancerInfo:
          ContainerName: "web"
          ContainerPort: "80"

taskdef.jsonの作成

今回はecsフォルダ配下にjsonファイルを作成します
ECSのタスク定義に以下の変数が入るようにします

  • NGINX_IMAGE_NAME
  • DJANGO_IMAGE_NAME

appspec.yml同様、CodeDeployの設定に追加します

ecs/taskdef.json
{
    "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/my-project-dev-back-taskdef:18",
    "containerDefinitions": [
        {
            "name": "web",
            "image": "<NGINX_IMAGE_NAME>",
            "cpu": 0,
            "links": [],
            "portMappings": [
                {
                    "containerPort": 80,
                    "hostPort": 80,
                    "protocol": "tcp"
                }
            ],
            "essential": true,
            "entryPoint": [],
            "command": [],
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [
                {
                    "sourceVolume": "tmp-data",
                    "containerPath": "/code/tmp"
                }
            ],
            "volumesFrom": [],
            "secrets": [],
            "dependsOn": [
                {
                    "containerName": "app",
                    "condition": "START"
                }
            ],
            "dnsServers": [],
            "dnsSearchDomains": [],
            "extraHosts": [],
            "dockerSecurityOptions": [],
            "dockerLabels": {},
            "ulimits": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/my-project/dev/back/nginx",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "my-project"
                },
                "secretOptions": []
            },
            "systemControls": []
        },
        {
            "name": "app",
            "image": "<DJANGO_IMAGE_NAME>",
            "cpu": 0,
            "links": [],
            "portMappings": [
                {
                    "containerPort": 8000,
                    "hostPort": 8000,
                    "protocol": "tcp"
                }
            ],
            "essential": true,
            "entryPoint": [
                "/usr/local/bin/entrypoint.prd.sh"
            ],
            "command": [],
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [
                {
                    "sourceVolume": "tmp-data",
                    "containerPath": "/code/tmp"
                }
            ],
            "volumesFrom": [],
            "secrets": [
                {
                    "name": "POSTGRES_NAME",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/POSTGRES_NAME"
                },
                {
                    "name": "POSTGRES_USER",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/POSTGRES_USER"
                },
                {
                    "name": "POSTGRES_PASSWORD",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/POSTGRES_PASSWORD"
                },
                {
                    "name": "POSTGRES_PORT",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/POSTGRES_PORT"
                },
                {
                    "name": "POSTGRES_HOST",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/POSTGRES_HOST"
                },
                {
                    "name": "SECRET_KEY",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/SECRET_KEY"
                },
                {
                    "name": "ALLOWED_HOSTS",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/ALLOWED_HOSTS"
                },
                {
                    "name": "AWS_DEFAULT_REGION_NAME",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/AWS_DEFAULT_REGION_NAME"
                },
                {
                    "name": "TRUSTED_ORIGINS",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/TRUSTED_ORIGINS"
                },
                {
                    "name": "DJANGO_SETTINGS_MODULE",
                    "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/my-project/dev/DJANGO_SETTINGS_MODULE"
                }
            ],
            "dnsServers": [],
            "dnsSearchDomains": [],
            "extraHosts": [],
            "dockerSecurityOptions": [],
            "dockerLabels": {},
            "ulimits": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/my-project/dev/back/django",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "my-project"
                },
                "secretOptions": []
            },
            "systemControls": []
        }
    ],
    "family": "my-project-dev-back-taskdef",
    "taskRoleArn": "arn:aws:iam::XXXXXXXXXXXX:role/service-role/ECSTaskRole-my-project-dev",
    "executionRoleArn": "arn:aws:iam::XXXXXXXXXXXX:role/service-role/ECSTaskExecutionRole-my-project-dev",
    "networkMode": "awsvpc",
    "revision": 18,
    "volumes": [
        {
            "name": "tmp-data",
            "host": {}
        }
    ],
    "status": "ACTIVE",
    "requiresAttributes": [
        {
            "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
        },
        {
            "name": "ecs.capability.execution-role-awslogs"
        },
        {
            "name": "com.amazonaws.ecs.capability.ecr-auth"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.17"
        },
        {
            "name": "com.amazonaws.ecs.capability.task-iam-role"
        },
        {
            "name": "ecs.capability.container-ordering"
        },
        {
            "name": "ecs.capability.execution-role-ecr-pull"
        },
        {
            "name": "ecs.capability.secrets.ssm.environment-variables"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
        },
        {
            "name": "ecs.capability.task-eni"
        }
    ],
    "placementConstraints": [],
    "compatibilities": [
        "EC2",
        "FARGATE"
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "512",
    "memory": "1024",
    "registeredAt": "2024-01-05T02:48:18.158Z",
    "registeredBy": "arn:aws:sts::XXXXXXXXXXXX:assumed-role/XXXXXXXXXXXX/XXXXXXXXXXXX",
    "tags": [
        {
            "key": "ProjectName",
            "value": "my-project"
        },
        {
            "key": "Environment",
            "value": "dev"
        }
    ]
}

実際に作成してみよう!

スタック作成時に必要な情報を入力していきます

スクリーンショット 2024-01-31 14.09.26.png

スクリーンショット 2024-01-31 14.10.05.png

スクリーンショット 2024-01-31 14.11.23.png

スクリーンショット 2024-01-31 14.11.48.png

以下のようにスタックの作成が完了したら成功です
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3632353938302f32376564613836362d623737322d623062662d643466342d3931313735623461623866612e706e67.png

ECS FargateのBlue/Greenデプロイが完了したら成功です

スクリーンショット 2024-01-31 22.09.24.png

スクリーンショット 2024-01-31 22.09.35.png

スクリーンショット 2024-01-31 22.10.53.png

スクリーンショット 2024-01-31 22.11.12.png

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?