CodePipelineでGitHubを利用したCI/CD構築


:::note warn
2024年7月25日をもって、CodeCommitが新規お客様向けのアクセスを閉じる事が決まった為、CodeCommitの代替え案としてGitHubを使用したCI/CDを構築しています。
:::
- このCI/CDは、CodePipelineを使用してアプリケーションをビルドし、ECSへデプロイしてサービスとして起動させる想定で作成したものの中から、代替え時に必要なファイルなどを抜粋して記載しています。
- 接続部分はマネジメントコンソールで作成
---

## 1.自分のGitHubでリポジトリを作る

私が今回作ったリポジトリ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912337/56ff431d-09bb-397c-5e9a-3e3e15d7209e.png)


- CFnを作っているVScodeとは別のVScodeを新しいウィンドウで開き、
手元にcloneしてREADMEを作成し、mainブランチにpushしておく。

---

## 2.AWSとGitHubの連携をする

今回はマネジメントコンソールから作成しました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912337/5e64c6f9-6368-9ef3-d131-5f92779bb3e2.png)


1. 左側のナビゲーションペインで『**設定**』>『**接続**』から接続を作成

2. プロバイダーを『**GitHub**』

3. 接続名を決める

4. GitHubに接続する　を選択し次のページ
『**新しいアプリをインストールする**』を押す
⇒GitHubの画面に切り替わるので、自分のGitHubと連携する

---

## 3.CodePiplineの設定


```jsx:codepipeline.yml
AWSTemplateFormatVersion: 2010-09-09
Description: CodePipeline for CI/CD

Parameters:
  SystemName:
    Type: String
  EnvType:
    Type: String
  GitHubRepo:
    Type: String
  GithubConnectionArn:
    Type: String
  GitHubBranch:
    Type: String

Mappings:
  AzMap:
    ap-northeast-1:
      1st: ap-northeast-1a
      2nd: ap-northeast-1c
      3rd: ap-northeast-1d

Resources:
  CodePipelineEcs:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      Name:  !Sub
        - ${SystemName}-${EnvType}-codepipeline-ecs
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      RoleArn: 
        Fn::ImportValue: !Sub
          - ${SystemName}-${EnvType}-role-codepipeline
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      ArtifactStore: 
        Type: S3
        Location: !Sub
          - ${SystemName}-${EnvType}-s3-cicd
          - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Stages: 
      # GitHubを使用する際に必要な要素
        - Name: Source
          Actions: 
            - InputArtifacts: []
              Name: Source
              ActionTypeId:
                Category: Source
                Owner: AWS
                Version: 1
                Provider: CodeStarSourceConnection
              OutputArtifacts:
                - Name: SourceArtifact
              Configuration:
                FullRepositoryId: !Ref GitHubRepo
                ConnectionArn: !Ref GithubConnectionArn
                BranchName: !Ref GitHubBranch
                DetectChanges: false
              RunOrder: 1
            
            # CodeCommitがあった時に必要だったもの。  
            # - Name: CodeCommit
            #   Region: !Ref AWS::Region
            #   RunOrder: 1
            #   ActionTypeId: 
            #     Category: Source
            #     Owner: AWS
            #     Provider: CodeCommit
            #     Version: 1
            #   Configuration: 
            #     RepositoryName: !Sub
            #       - ${SystemName}-${EnvType}-codecommit-ecs
            #       - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
            #     BranchName: main
            #     PollForSourceChanges: true
            #     OutputArtifactFormat: CODE_ZIP
            #   OutputArtifacts: 
            #     - Name: SourceArtifact
            #   Namespace: SourceVariables 

        - Name: Build
          Actions: 
            - Name: CodeBuild
              Region: !Ref AWS::Region
              RunOrder: 1
              ActionTypeId: 
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: 1
              Configuration: 
                ProjectName: !Sub
                  - ${SystemName}-${EnvType}-codebuild-ecs
                  - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
              InputArtifacts: 
                - Name: SourceArtifact
              OutputArtifacts: 
                - Name: BuildArtifact
              Namespace: BuildVariables 

        - Name: Deploy
          Actions: 
          - Name: CodeDeploy
            Region: !Ref AWS::Region
            RunOrder: 1
            ActionTypeId: 
              Category: Deploy
              Owner: AWS
              Provider: CodeDeployToECS
              Version: 1
            InputArtifacts: 
              - Name: BuildArtifact
            Configuration: 
              ApplicationName: !Sub 
                - ${SystemName}-${EnvType}-codedeploy-ecs
                - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
              DeploymentGroupName: !Sub 
                - ${SystemName}-${EnvType}-deploygroup-ecs
                - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
              TaskDefinitionTemplateArtifact: BuildArtifact
              TaskDefinitionTemplatePath: taskdef.json
              AppSpecTemplateArtifact: BuildArtifact
              AppSpecTemplatePath: appspec.yml

      Tags: 
        - Key: Name
          Value: !Sub
            - ${SystemName}-${EnvType}-codepipeline-ecs
            - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType

```

```jsx:dev-parameters.json
{
    "Parameters": [
        {
            "ParameterKey": "SystemName",
            "ParameterValue": "cicd"
        },
        {
            "ParameterKey": "EnvType",
            "ParameterValue": "dev"
        },
        {
            "ParameterKey": "GitHubRepo",
            "ParameterValue": "GitHubユーザー名/リポジトリ名"
        },
        {
            "ParameterKey": "GithubConnectionArn",
            "ParameterValue": "arn:aws:codestar-connections:<region>:<account-id>:connection/<connection-id>"
        },
        {
            "ParameterKey": "GitHubBranch",
            "ParameterValue": "main"
        }
    ]
}

```

`GitHubRepo`

- GitHubユーザー名/リポジトリ名

`GithubConnectionArn`

- ２で作った接続部分のARN

```jsx
arn:aws:codestar-connections:<region>:<account-id>:connection/<connection-id>
```

`GitHubBranch`

- どこのブランチを使うか

---

## 4.CodePipline用のIAMロールの設定

`RoleCodePipeline:` の部分を変更しています

- Connectionへのアクセス権限を追加

```jsx:iam.yml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM for CI/CD

Parameters:
  SystemName:
    Type: String
  EnvType:
    Type: String
  GithubConnectionArn:
    Type: String
Mappings:
  AzMap:
    ap-northeast-1:
      1st: ap-northeast-1a
      2nd: ap-northeast-1c
      3rd: ap-northeast-1d

Resources:
  RoleEcsExecution:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub
        - ${SystemName}-${EnvType}-role-ecs-execution
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Description: !Sub
        - ${SystemName}-${EnvType}-role-ecs-execution
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Path: /
      # AssumeRolePolicyDocument: {\Version\:\2012-10-17\,\Statement\:[{\Effect\:\Allow\,\Principal\:{\Service\:\ec2.amazonaws.com\},\Action\:\sts:AssumeRole\}]}
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement: 
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
      Tags: 
        - Key: Name
          Value: !Sub
            - ${SystemName}-${EnvType}-role-ecs-execution
            - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType

  RoleEcsAutoScaling:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub
        - ${SystemName}-${EnvType}-role-ecs-autoscaling
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Description: !Sub
        - ${SystemName}-${EnvType}-role-ecs-autoscaling
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Path: /
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement: 
          - Effect: Allow
            Principal:
              Service: ecs.application-autoscaling.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole
      Tags: 
        - Key: Name
          Value: !Sub
            - ${SystemName}-${EnvType}-role-ecs-autoscaling
            - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType

  RoleCodeBuild:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub
        - ${SystemName}-${EnvType}-role-codebuild
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Description: !Sub
        - ${SystemName}-${EnvType}-role-codebuild
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Path: /
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement: 
          - Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AWSCodeBuildDeveloperAccess
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
        - arn:aws:iam::aws:policy/AmazonS3FullAccess
        - arn:aws:iam::aws:policy/AmazonECS_FullAccess
        - arn:aws:iam::aws:policy/CloudWatchFullAccess
      Tags: 
        - Key: Name
          Value: !Sub
            - ${SystemName}-${EnvType}-role-codebuild
            - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType

  RoleCodeDeploy:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub
        - ${SystemName}-${EnvType}-role-codedeploy
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Description: !Sub
        - ${SystemName}-${EnvType}-role-codedeploy
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Path: /
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement: 
          - Effect: Allow
            Principal:
              Service: codedeploy.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AWSCodeDeployRoleForECS
      Tags: 
        - Key: Name
          Value: !Sub
            - ${SystemName}-${EnvType}-role-codedeploy
            - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType
          
          
# CodePipelineのIAM設定/Connectionへのアクセス権限を追加
  RoleCodePipeline:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub
        - ${SystemName}-${EnvType}-role-codepipeline
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Description: !Sub
        - ${SystemName}-${EnvType}-role-codepipeline
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
      Path: /
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement: 
          - Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AWSCodePipeline_FullAccess
        - arn:aws:iam::aws:policy/AWSCodeCommitFullAccess
        - arn:aws:iam::aws:policy/AWSCodeBuildDeveloperAccess
        - arn:aws:iam::aws:policy/AmazonS3FullAccess
        - arn:aws:iam::aws:policy/AWSCodeDeployFullAccess
        - arn:aws:iam::aws:policy/AmazonECS_FullAccess
      Policies:
        - PolicyName: CodeStarConnectionsAccess
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: 
                  - codestar-connections:UseConnection
                  - codestar-connections:GetConnection
                  - codestar-connections:ListConnections
                Resource: !Ref GithubConnectionArn
      Tags: 
        - Key: Name
          Value: !Sub
            - ${SystemName}-${EnvType}-role-codepipeline
            - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
        - Key: SystemName
          Value: !Ref SystemName
        - Key: EnvType
          Value: !Ref EnvType


Outputs:
  RoleEcsExecution:
    Value: !GetAtt RoleEcsExecution.Arn
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-role-ecs-execution
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  RoleEcsAutoScaling:
    Value: !GetAtt RoleEcsAutoScaling.Arn
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-role-ecs-autoscaling
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  RoleCodeBuild:
    Value: !GetAtt RoleCodeBuild.Arn
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-role-codebuild
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  RoleCodeDeploy:
    Value: !GetAtt RoleCodeDeploy.Arn
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-role-codedeploy
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
  RoleCodePipeline:
    Value: !GetAtt RoleCodePipeline.Arn
    Export:
      Name: !Sub
        - ${SystemName}-${EnvType}-role-codepipeline
        - {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
```

```jsx:dev-parameters.json
{
    "Parameters": [
        {
            "ParameterKey": "SystemName",
            "ParameterValue": "cicd"
        },
        {
            "ParameterKey": "EnvType",
            "ParameterValue": "dev"
        },
        {
            "ParameterKey": "GithubConnectionArn",
            "ParameterValue": "arn:aws:codestar-connections:<region>:<account-id>:connection/<connection-id>"
        }
    ],
    "Capabilities": [
        "CAPABILITY_NAMED_IAM"
    ]
}

```
`GithubConnectionArn`

- ２で作った接続部分のARN

```jsx
arn:aws:codestar-connections:<region>:<account-id>:connection/<connection-id>
```


---

## 5.完成

- GitHubと連携したリポジトリにpushを行う

![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912337/b6521365-e5e0-3472-d411-ba07932a4359.png)

- 完成後、Dockerfile・buildspec.ymlなどもリポジトリに格納し、CodeBuild→CodeDeploy~と構築していく

---

### 参考

[CodePipelineとGiuhubを連携させてECS自動デプロイするCloudformation - Qiita](https://qiita.com/theFirstPenguin/items/996f1b7bca92837c9f20)

[CloudFormation CodePipeline で Github v2 用コネクションを使ってGithubからソースコードを取得する - Qiita](https://qiita.com/furu8ma/items/a35bfa4dc6504f8d3422)

[CodePipelineのソースにGitHubのリポジトリを利用する方法@CloudFormation](https://zenn.dev/taroman_zenn/articles/4007a33384c6ad)

[CodeStarSourceConnection for Bitbucket Cloud, GitHub, GitHub Enterprise Server, GitLab.com, and GitLab self-managed actions - AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodestarConnectionSource.html#action-reference-CodestarConnectionSource-input)