1
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?

More than 1 year has passed since last update.

CodePipelineとGiuhubを連携させてECS自動デプロイするCloudformation

Last updated at Posted at 2021-09-12

はじめに

CodePipelineをなんとなく使っていたのですが、いろいろな間違いに気づいたので正しい理解をメモしておきます。

AWSとGithubを連携させるやりかた

特定のブランチ(例えばdevelop)にマージすると自動的にECSサービスが更新されるようにします。
version1とversion2の2つのやり方があり、現在はVersion2が推奨されています。

【version1】 GithubのPersonal Access Tokenを使う

ググるとこの方法がよく出てきますが、今は非推奨とのことです。
後述するCodeStarSourceConnectionを使いましょう。

Not recommended: The GitHub version 1 action uses OAuth tokens to authenticate with GitHub and uses a separate webhook to detect changes. This is no longer the recommended method.

CodePipeline.yml
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  GitHubRepositoryName:
    Type: String
    Default: <inut-your-github-repo>
  GitHubAccountName:
    Type: String
    Default: <inut-your-github-account>
  GitHubPipelineWebhookName:
    Type: String
    Default: <inut-your-unique-webhook-name> # レポジトリ内の他のwebhookと被らないようにする
  CodeBuildVpcId:
    Type: String
    Default: <input-your-vpc-id-for-codebuild>
  CodeBuildPrivateSubnet1:
    Type: String
    Default: <input-your-subnet-id-for-codebuild>
  CodeBuildPrivateSubnet2:
    Type: String
    Default: <input-your-subnet-id-for-codebuild>
  CodeBuildPrivateSubnet3:
    Type: String
    Default: <input-your-subnet-id-for-codebuild>
  CodeBuildVpcDefaultSG:
    Type: String
    Default: <input-your-default-security-group-for-codebuild>
  EcrRepository:
    Type: String
    Default: <input-your-ECR-repo>
  Branch:
    Type: String
    Default: <input-your-Github-branch-for-CodePipeline>
  ClusterName:
    Type: String
    Default: <inout-your-ECS-cluster-name>
  ServiceName:
    Type: String
    Default: <input-your-ECS-service-name>
  ArtifactFileName:
    Type: String
    Default: artifact.json
  CodeBuildName:
    Type: String
    Default: <input-your-codebuild-name> #なんでもOK
  CodeBuildServiceRoleArn:
    Type: String
    Default: <input-your-service-role-arn>
  CodePipelineRoleArn:
    Type: String
    Default: <input-your-service-role-arn>
  S3ArficactStoreBucketName:
    Type: String
    Default: <input-your-s3-bucket-name>

Resources:
  CodeBuild:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: !Ref CodeBuildName
      ServiceRole: !Ref CodeBuildServiceRoleArn
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Type: LINUX_CONTAINER
        Image: aws/codebuild/standard:5.0
        PrivilegedMode: true
        EnvironmentVariables:
          - Name: AWS_DEFAULT_REGION
            Value: !Sub ${AWS::Region}
          - Name: AWS_ACCOUNT_ID
            Value: !Sub ${AWS::AccountId}
          - Name: REPOSITORY_URI
            Value: !Sub
              - ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${Repository}
              - Repository: !Ref EcrRepository
          - Name: CONTAINER_NAME
            Value: !Ref ServiceName
      Artifacts:
        Type: CODEPIPELINE
      Source:
        Type: CODEPIPELINE
        BuildSpec: buildspec.yml
      VpcConfig:
        VpcId: !Ref CodeBuildVpcId
        Subnets:
          - !Ref CodeBuildPrivateSubnet1
          - !Ref CodeBuildPrivateSubnet2
          - !Ref CodeBuildPrivateSubnet3
        SecurityGroupIds:
          - !Ref CodeBuildVpcDefaultSG
        # 今回はCodeBuildを実行するための特定のVPC/Subnet/SGを設定する。これを設定しないと他のAWSユーザと共通IPからdockerイメージをpullすることとなり、pullリミットに引っかかる。
        # Private Subnetの必要があり、NatGWも必要。
        # 詳細 => https://docs.aws.amazon.com/codebuild/latest/userguide/vpc-support.html

  PipelineWebhook:
    Type: 'AWS::CodePipeline::Webhook'
    Properties:
      Authentication: GITHUB_HMAC
      AuthenticationConfiguration:
        SecretToken: '{{resolve:secretsmanager:<your-secret-name>:SecretString:<your-secret-key>}}'
        # Parametersを使って機密情報を入れるのは推奨されない。今回はSecretManagerを使う。
        # 詳細 => https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-secretsmanager
      Filters:
        - JsonPath: '$.ref'
          MatchEquals: !Sub
            - refs/heads/${Branch}
            - Branch: !Ref Branch
        - JsonPath: '$.created'
          MatchEquals: false
        - JsonPath: '$.deleted'
          MatchEquals: false
        # 特定のBranchの変更(push)を検知してwebhookを実行。このときBranchの作成と消去は無視する。
        # 詳しくは、Githubの Settings => Webhooks => Recent Deliveries => Payload を見ればわかる。
      TargetPipeline: !Ref Pipeline
      TargetAction: SourceAction
      Name: !Ref GitHubPipelineWebhookName
      TargetPipelineVersion: !GetAtt Pipeline.Version
      RegisterWithThirdParty: 'true'

  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !Ref CodePipelineRoleArn
      Name: !Ref ServiceName
      ArtifactStore:
        Type: S3
        Location: !Ref S3ArficactStoreBucketName
        # 事前にS3バケットを作っておく
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: ThirdParty
                Version: 1
                Provider: GitHub
              Configuration:
                Owner: !Ref GitHubAccountName
                Repo: !Ref GitHubRepositoryName
                PollForSourceChanges: false
                # Webhhokを登録してGithub→AWSに変更を教えてもらうのではなく、AWS側がポーリングすることでGithubの変更をキャッチするための設定。昔はこれが主流だったらしい。今回は使わない。
                # 詳細 => https://aws.amazon.com/jp/premiumsupport/knowledge-center/codepipeline-running-twice/
                Branch: !Ref Branch
                OAuthToken: '{{resolve:secretsmanager:<your-secret-name>:SecretString:<your-secret-key>}}'
              RunOrder: 1
              OutputArtifacts:
                - Name: SourceCode
        - Name: Build
          Actions:
            - Name: Build
              ActionTypeId:
                Category: Build
                Owner: AWS
                Version: 1
                Provider: CodeBuild
              Configuration:
                ProjectName: !Ref CodeBuild
              RunOrder: 1
              InputArtifacts:
                - Name: SourceCode
              OutputArtifacts:
                - Name: BuildOutput
        - Name: Deploy
          Actions:
            - Name: Deploy
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: 1
                Provider: ECS
              Configuration:
                ClusterName: !Ref ClusterName
                ServiceName: !Ref ServiceName
                FileName: !Ref ArtifactFileName
              InputArtifacts:
                - Name: BuildOutput
              RunOrder: 1
buildspec.yml
version: 0.2

phases:
  pre_build:
    commands:
      - IMAGE_URI="${REPOSITORY_URI}:$(echo ${CODEBUILD_RESOLVED_SOURCE_VERSION} | head -c 7)"
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
  build:
    commands:
      - echo Build started on $(date)
      - docker build --tag ${IMAGE_URI} .
      - docker push ${IMAGE_URI}
  post_build:
    commands:
      - echo Build completed on $(date)
      - printf '[{"name":"%s","imageUri":"%s"}]' "${CONTAINER_NAME}" "$IMAGE_URI" > artifact.json

artifacts:
  files: artifact.json
..Dockerfile
# 適当につくってください。

【version2】 CodeStarSourceConnectionを使う

今はこちらが推奨されているみたいです。
CodeStarSourceConnectionはコンソール( Developer Tools => Settings => Connnections )から作るのが早いです。
https://docs.aws.amazon.com/dtconsole/latest/userguide/connections-create-github.html#connections-create-github-console

下図から、接続先のGithubアカウントまたはレポジトリを選びます。
スクリーンショット 2022-04-12 11.31.41.png

下記のようにymlを書き直します。Webhookの設定も不要となります。

Recommended: The GitHub version 2 action uses Github app-based auth backed by a CodeStarSourceConnection for Bitbucket, GitHub, and GitHub Enterprise Server actions resource. It installs an AWS CodeStar Connections application into your GitHub organization so that you can manage access in GitHub.

CodePipeline.yml
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  GitHubRepositoryName:
    Type: String
    Default: <inut-your-github-repo>
  GitHubAccountName:
    Type: String
    Default: <inut-your-github-account>
  CodeBuildVpcId:
    Type: String
    Default: <input-your-vpc-id-for-codebuild>
  CodeBuildPrivateSubnet1:
    Type: String
    Default: <input-your-subnet-id-for-codebuild>
  CodeBuildPrivateSubnet2:
    Type: String
    Default: <input-your-subnet-id-for-codebuild>
  CodeBuildPrivateSubnet3:
    Type: String
    Default: <input-your-subnet-id-for-codebuild>
  CodeBuildVpcDefaultSG:
    Type: String
    Default: <input-your-default-security-group-for-codebuild>
  EcrRepository:
    Type: String
    Default: <input-your-ECR-repo>
  Branch:
    Type: String
    Default: <input-your-Github-branch-for-CodePipeline>
  ClusterName:
    Type: String
    Default: <inout-your-ECS-cluster-name>
  ServiceName:
    Type: String
    Default: <input-your-ECS-service-name>
  ArtifactFileName:
    Type: String
    Default: artifact.json
  CodeBuildName:
    Type: String
    Default: <input-your-codebuild-name> 
  CodeBuildServiceRoleArn:
    Type: String
    Default: <input-your-service-role-arn>
  CodePipelineRoleArn:
    Type: String
    Default: <input-your-service-role-arn>
  S3ArficactStoreBucketName:
    Type: String
    Default: <input-your-s3-bucket-name>
  GithubConnectionArn: # ここに作ったCodeStarSourceConnectionのARNを記入
    Type: String
    Default: <input-your-connection-arn>

Resources:
  CodeBuild:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: !Ref CodeBuildName
      ServiceRole: !Ref CodeBuildServiceRoleArn
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Type: LINUX_CONTAINER
        Image: aws/codebuild/standard:5.0
        PrivilegedMode: true
        EnvironmentVariables:
          - Name: AWS_DEFAULT_REGION
            Value: !Sub ${AWS::Region}
          - Name: AWS_ACCOUNT_ID
            Value: !Sub ${AWS::AccountId}
          - Name: REPOSITORY_URI
            Value: !Sub
              - ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${Repository}
              - Repository: !Ref EcrRepository
          - Name: CONTAINER_NAME
            Value: !Ref ServiceName
      Artifacts:
        Type: CODEPIPELINE
      Source:
        Type: CODEPIPELINE
        BuildSpec: buildspec.yml
      VpcConfig:
        VpcId: !Ref CodeBuildVpcId
        Subnets:
          - !Ref CodeBuildPrivateSubnet1
          - !Ref CodeBuildPrivateSubnet2
          - !Ref CodeBuildPrivateSubnet3
        SecurityGroupIds:
          - !Ref CodeBuildVpcDefaultSG

  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !Ref CodePipelineRoleArn
# 上記RoleにConnectionへのアクセス権限を追加する必要あり。
#{
#    "Version": "2012-10-17",
#    "Statement": [
#      {
#        "Sid": "ConnectionsAccess",
#        "Effect": "Allow",
#        "Action": [
#            "codestar-connections:UseConnection",
#            "codestar-connections:GetConnection",
#            "codestar-connections:ListConnections"
#        ],
#        "Resource": "<input-your-connection-arn>"
#     }
#   ]
#}
      Name: !Ref ServiceName
      ArtifactStore:
        Type: S3
        Location: !Ref S3ArficactStoreBucketName
      Stages:
        - Name: Source # updated
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: AWS
                Version: 1
                Provider: CodeStarSourceConnection
              OutputArtifacts:
                - Name: SourceCode
              Configuration:
                FullRepositoryId: !Sub
                  - ${OrganizationName}/${RepositoryName}
                  - OrganizationName: !Ref GitHubAccountName
                    RepositoryName: !Ref GitHubRepositoryName
                ConnectionArn: !Ref GithubConnectionArn
                BranchName: !Ref Branch
                OutputArtifactFormat: CODEBUILD_CLONE_REF
              RunOrder: 1
        - Name: Build
          Actions:
            - Name: Build
              ActionTypeId:
                Category: Build
                Owner: AWS
                Version: 1
                Provider: CodeBuild
              Configuration:
                ProjectName: !Ref CodeBuild
              RunOrder: 1
              InputArtifacts:
                - Name: SourceCode
              OutputArtifacts:
                - Name: BuildOutput
        - Name: Deploy
          Actions:
            - Name: Deploy
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: 1
                Provider: ECS
              Configuration:
                ClusterName: !Ref ClusterName
                ServiceName: !Ref ServiceName
                FileName: !Ref ArtifactFileName
              InputArtifacts:
                - Name: BuildOutput
              RunOrder: 1

↓こちらの記事を参考にさせていただきました。

1
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
1
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?