LoginSignup
0
0

AWS CloudFormationでCodePipelineを使ったCI/CD環境構築

Last updated at Posted at 2024-04-26

WebアプリケーションをEC2で稼働させる時、毎回EC2にアクセスしてファイルを更新するのが手間と感じたので、CodeBuild, CodeDeploy,CodePipelineを使用して自動化してみました。

似たような環境を複数(再度)使用する可能性があったので 、CloudFormationを使用して一気に作成することにします。

完成アーキテクチャはこんな感じ
AWSArchitecture.png

①ローカルで開発したWebアプリケーションをGitHubにプッシュ
②CodePipelineが定期的にGitHubに確認に行き更新がないかチェック
③更新があったら最新コードを取得
④S3に取得したコードを保存
⑤CodeBuildにビルド実行指示
⑥S3からビルド用コードを取得
⑦ビルドを実行してアーティファクト(.zip)を作成
⑧S3に保存
⑨CodePipelineからCodeDeployにデプロイの実行指示
⑩CodeDeployの設定に合わせてデプロイを開始
⑪CodeDeployからEC2にデプロイ指示
⑫EC2からS3にアプリケーションを取得しに行って実行

これでローカル編集したコードをGitHubにPushすれば、自動で公開されているEC2のWebアプリケーションが更新されます。

※GitHubの情報をSecretManagerから参照させるようにしているので、事前にOwner, Repo, OAuthToken 情報をSecretManagerに登録しておいてください(CloudFormationのコードに直接入力して動作確認でも可)。

CloudFormationのコードが300行超えているのでサービス別のコードの最後に全体を載せます。

共通部分

・パラメータとしてCloudFormationスタック作成時値を指定します。
WebAppS3BucketName: 作成するS3のバケット名
GitHubRepoURL: コードを保存しているGitHubのリポジトリURL
EC2InstanceName: Webアプリを実行するEC2名(デフォルト値設定あり)

AWSTemplateFormatVersion: '2010-09-09'
Description: |
  Example CloudFormation template for creating an S3 bucket and a CodeBuild project for a web application pushed to GitHub.

Parameters:
  WebAppS3BucketName:
    Type: String
    Description: Enter the name for the S3 bucket to host the web application static files

  GitHubRepoURL:
    Type: String
    Description: Enter the URL of your GitHub repository

  EC2InstanceName:
    Type: String
    Default: WebApplicationPipelineEC2
    Description: Enter the name for the EC2 instance

EC2

・EC2を設置するVPCとSubnetを作成

Resources:
  # VPC 作成
  WebAppVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: '10.0.0.0/16'
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: WebApplicationPipelineVPC

  # Subnet 作成
  WebAppSubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref WebAppVPC
      CidrBlock: '10.0.0.0/24'
      AvailabilityZone: 'ap-northeast-1a'
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: WebApplicationPipelineSubnet

EC2用のセキュリティグループ作成

・インバウンド許可ポート: SSH/22, HTML/80, Webアプリケーション/8080

  # EC2用SecurityGroup 作成
  MyEC2SecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: EC2 Security Group for MyEC2Instance
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0  # SSHアクセスを許可するCIDR
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0  # HTTPアクセスを許可するCIDR
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          CidrIp: 0.0.0.0/0  # その他のポートにアクセスを許可するCIDR

Webアプリケーションを実行するEC2作成

・SecurityGroupIds: 作成したSecutiryGroup[MyEC2SecurityGroup]を指定
・KeyName: 事前に作成していたキーペア名を指定(各自で作成)
・IamInstanceProfile: IAM Roleを割り当てたインスタンスプロファイル(後で作成)
・Tags: - Key: Name Value: !Ref EC2InstanceName: Parametersで入力したEC2名を設定
・UserData: EC2起動時に実行するコマンド 内容はコメント参考
   (OrenoApplicationは各自のアプリケーション名に変更)

  MyEC2Instance: # EC2インスタンス 作成
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: ami-04e0b6d6cfa432943  # EC2インスタンスに使用するAMIのIDを指定してください
      InstanceType: t2.micro  # EC2インスタンスタイプ
      SecurityGroupIds:
        - !Ref MyEC2SecurityGroup  # セキュリティグループ
      KeyName: OrenoSecurityKey  # キーペア名(作成済)
      IamInstanceProfile: !Ref EC2InstanceProfile
      Tags:
        - Key: Name
          Value: !Ref EC2InstanceName
      UserData:
        Fn::Base64: |
          #!/bin/bash
          # モジュールの最新化
          sudo yum update -y

          # Javaのインストール
          sudo yum install -y java-17

          # CodeDeploy エージェントインストール
          sudo yum install -y ruby
          wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install
          chmod +x ./install
          sudo ./install auto

          # Create a sample service script
          cat > /etc/systemd/system/orenoapplication.service << EOF
          [Unit]
          Description=OrenoApplication
          After=syslog.target

          [Service]
          User=ec2-user
          ExecStart=/usr/bin/java -jar /home/ec2-user/app/OrenoApplication-0.0.1-SNAPSHOT.jar
          WorkingDirectory=/home/ec2-user/app

          [Install]
          WantedBy=multi-user.target
          EOF

          # Enable and start the service
          systemctl daemon-reload

EC2用IAM Role作成

※EC2はインスタンスプロファイルを作成してEC2に設定する必要あり

EC2InstanceProfile: # EC2用インスタンスプロファイル
  Type: "AWS::IAM::InstanceProfile"
  Properties:
    Path: "/"
    Roles:
      - !Ref EC2Role

EC2Role: # EC2用ロール
  Type: 'AWS::IAM::Role'
  Properties:
    AssumeRolePolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: Allow
          Principal:
            Service: ec2.amazonaws.com
          Action: 'sts:AssumeRole'
    Policies:
      - PolicyName: S3FullAccessPolicy
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action:
                - 's3:*'
              Resource: '*'

S3バケット作成

・Properties: BucketName: !Ref WebAppS3BucketName: Parametersで入力したS3名を設定
※同じ名前のS3バケットは作成できない為、別環境で作成する場合のS3バケット名重複注意

  # S3 バケット
  WebAppS3Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Ref WebAppS3BucketName

CodeBuildプロジェクト作成

・Location: !Sub 'arn:aws:s3:::${WebAppS3Bucket}': 先に作成したS3のARNを取得
・その他は各行のコメントを参考にしてください(一番最初に作ったのでコメント過多)
※SourceでGitHubのURLを指定していますが後ほど作るCodePipelineでは、GitHubのソースコードをS3に一度保存します。CodeBuildはS3に保存されたソースコードに対して実行されます(作成されたCodeBuildを手動で実行するとGitHubから直接ビルドを行います)。

  # CodeBuildプロジェクト定義
  CodeBuildProject:
    Type: 'AWS::CodeBuild::Project' # リソースタイプ AWS CodeBuild Project
    Properties:
      Name: WebApplicationPipelineCodeBuild # プロジェクト名
      Description: CodeBuild project for building and deploying web application # プロジェクト説明
      ServiceRole: !GetAtt CodeBuildRole.Arn # CodeBuildが使用するIAMロールARN
      Artifacts: # アーティファクト設定
        Type: S3 # 保存先 S3
        Location: !Sub 'arn:aws:s3:::${WebAppS3Bucket}' # S3バケットのARNを指定
        Packaging: ZIP # アーティファクトのパッケージング ZIP
      Environment: # ビルド環境
        ComputeType: BUILD_GENERAL1_SMALL # コンピューティングタイプ
        Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0 # コンピューティングイメージ
        Type: LINUX_CONTAINER # コンピューティングタイプ
        EnvironmentVariables: # 環境変数
          - Name: S3_BUCKET # 環境変数名 S3バケット
            Type: PLAINTEXT # 環境変数タイプ プレーンテキストで処理
            Value: WebAppS3BucketName # 環境変数値 S3バケット名
      Source: # ソースの設定
        Type: GITHUB # ソースの種類 GitHub
        Location: !Ref GitHubRepoURL # GitHubリポジトリのURL
        GitCloneDepth: 1 # ソースのクローン数
        BuildSpec: buildspec.yml # ソースのビルドスペック

CodeBuildRole用IAM Role作成

・アーティファクトを保存するのにS3へのPutObject, ビルドする為のコードを取得する為にGetObjectを設定
・logs: 関連の実行許可も必須
・ここもその他は各行のコメントを参考にしてください。

  CodeBuildRole: # CodeBuild IAM ロール定義
    Type: 'AWS::IAM::Role' # リソースタイプ AWS IAM Role
    Properties: # プロパティ設定
      AssumeRolePolicyDocument: # IAMロールのAssumeRolePolicyDocument
        Version: '2012-10-17' # IAMロールポリシーのバージョン
        Statement: # ステートメント
          - Effect: Allow # 許可設定
            Principal: # プリンシパル設定
              Service: codebuild.amazonaws.com # IAMロールのサービス CodeBuild
            Action: 'sts:AssumeRole' # IAMロールのアクション sts:AssumeRole 一時的セキュリティトーン取得
      Policies: # ロールポリシー
        - PolicyName: CodeBuildPolicy # ロールポリシー名
          PolicyDocument: # ロールポリシーのドキュメント
            Version: '2012-10-17' # ロールポリシーのバージョン
            Statement: # ステートメント
              - Effect: Allow # 許可設定
                Action: # 実行許可アクション
                  - 's3:PutObject' # S3へのアップロード
                  - 's3:GetObject' # S3からのダウンロード
                Resource: !Sub 'arn:aws:s3:::${WebAppS3Bucket}/*' # 特定のS3バケットのオブジェクトへのアクセス
              - Effect: Allow # 許可設定
                Action: # 実行許可アクション
                  - 'logs:CreateLogGroup' # ロググループの作成
                  - 'logs:CreateLogStream' # ログストリームの作成
                  - 'logs:PutLogEvents' # ログの記録
                Resource: '*' # すべにアクセス

CodeDeployアプリケーション作成

  CodeDeployApplication: # CodeDeployアプリケーション
    Type: 'AWS::CodeDeploy::Application'
    Properties:
      ApplicationName: CodeDeployApplication

CodeDeployGroup作成

・ApplicationName: 先に作成したCodeDeployApplication名を取得
・DeploymentConfigName: AllAtOnce(デプロイを一度に行う)
・Ec2TagFilters: Key: Name, Value: !Ref EC2InstanceName: KeyとValueを使用してデプロイメントグループを特定するためTypeはKEY_AND_VALUEを指定。

  CodeDeployDeploymentGroup:
    Type: 'AWS::CodeDeploy::DeploymentGroup'
    Properties:
      DeploymentGroupName: CodeDeployDeploymentGroup
      ApplicationName: !Ref CodeDeployApplication
      ServiceRoleArn: !GetAtt CodeDeployRole.Arn  # CodeDeployが使用するIAMロールのARNを指定してください
      DeploymentConfigName: CodeDeployDefault.AllAtOnce  # デプロイメントの構成
      Ec2TagFilters:  # EC2タグを使用してデプロイメントグループをフィルタリング
        - Key: Name
          Value: !Ref EC2InstanceName # EC2インスタンス名(今回は作成済)
          Type: KEY_AND_VALUE # KEY_ONLY: 指定したキーのみ, VALUE_ONLY: 指定した値のみ, KEY_AND_VALUE: 指定したキーと値

CodeDeploy用IAM Roleを作成

・全て許可にしているので、本来は絞るべき

  CodeDeployRole: # CodeDeploy用ロール
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: codedeploy.amazonaws.com
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: CodeDeployPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: '*'
                Resource: '*'

CodePipelineを作成

・作成したCodeBuild, CodeDeployの情報を基に設定
・SourceAction: GitHubのリポジトリを指定する
   リポジトリのオーナー Owner
   リポジトリ名 Repo
   OAuthトークン OAuthToken(事前にGitHubで作成 設定する権限注意)
'{{resolve:secretsmanager:GitHubSecret:SecretString:Owner}}': SecretManagerのGitHubSecretという作成したシークレット内の値を参照させる(シークレットは別途作成しておいてください)

  WebAppCodePipeline: # CodePipeline
    Type: 'AWS::CodePipeline::Pipeline'
    Properties:
      ArtifactStore:
        Location: !Ref WebAppS3BucketName
        Type: S3
      RoleArn: !GetAtt CodePipelineRole.Arn
      
      # ソースステージの設定
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: ThirdParty
                Provider: GitHub
                Version: 1
              Configuration:
                Owner: '{{resolve:secretsmanager:GitHubSecret:SecretString:Owner}}' # GitHubのリポジトリのオーナー
                Repo: '{{resolve:secretsmanager:GitHubSecret:SecretString:Repo}}'  # GitHubのリポジトリ名
                Branch: main
                OAuthToken: '{{resolve:secretsmanager:GitHubSecret:SecretString:OAuthToken}}'  # GitHubのOAuthトークン
              OutputArtifacts:
                - Name: SourceOutput
          
        # ビルドステージの設定
        - Name: PiplineBuild
          Actions:
            - Name: BuildAction
              ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: 1
              Configuration:
                ProjectName: WebApplicationPipelineCodeBuild
              InputArtifacts:
                - Name: SourceOutput
              OutputArtifacts:
                - Name: BuildOutput
          
        # デプロイステージの設定
        - Name: PiplineDeploy
          Actions:
            - Name: DeployAction
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CodeDeploy
                Version: 1
              Configuration:
                ApplicationName: CodeDeployApplication
                DeploymentGroupName: CodeDeployDeploymentGroup
              InputArtifacts:
                - Name: BuildOutput

CodePipeline用IAM Role作成

・CodeBuildとCodeDeployで使用する実行許可を付与する

  CodePipelineRole: # CodePipeline用ロール
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: CodePipelinePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
            - Effect: Allow # 許可設定
              Action: # 実行許可アクション
                - 's3:PutObject' # S3へのアップロード
                - 's3:GetObject' # S3からのダウンロード
              Resource: !Sub 'arn:aws:s3:::${WebAppS3Bucket}/*' # 特定のS3バケットのオブジェクトへのアクセス
            - Effect: Allow # 許可設定
              Action: # 実行許可アクション
                - 'logs:CreateLogGroup' # ロググループの作成
                - 'logs:CreateLogStream' # ログストリームの作成
                - 'logs:PutLogEvents' # ログの記録
              Resource: '*' # すべにアクセス
        - PolicyName: PiplineCodeBuildDeployPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'codebuild:StartBuild'
                  - 'codebuild:BatchGetBuilds'
                Resource: !GetAtt CodeBuildProject.Arn
              - Effect: Allow
                Action:
                  - 'codedeploy:CreateDeployment'
                  - 'codedeploy:GetDeployment'
                  - 'codedeploy:GetDeploymentConfig'
                  - 'codedeploy:GetApplicationRevision'
                  - 'codedeploy:RegisterApplicationRevision'
                Resource: '*'

最後に全体のコードを載せておきます。

AWSTemplateFormatVersion: '2010-09-09'
Description: |
  Example CloudFormation template for creating an S3 bucket and a CodeBuild project for a web application pushed to GitHub.

Parameters:
  WebAppS3BucketName:
    Type: String
    Description: Enter the name for the S3 bucket to host the web application static files

  GitHubRepoURL:
    Type: String
    Description: Enter the URL of your GitHub repository

  EC2InstanceName:
    Type: String
    Default: WebApplicationPipelineEC2
    Description: Enter the name for the EC2 instance

Resources:
  # VPC 作成
  WebAppVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: '10.0.0.0/16'
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: WebApplicationPipelineVPC

  # Subnet 作成
  WebAppSubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref WebAppVPC
      CidrBlock: '10.0.0.0/24'
      AvailabilityZone: 'ap-northeast-1a'
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: WebApplicationPipelineSubnet


  # EC2用SecurityGroup 作成
  MyEC2SecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: EC2 Security Group for MyEC2Instance
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0  # SSHアクセスを許可するCIDR
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0  # HTTPアクセスを許可するCIDR
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          CidrIp: 0.0.0.0/0  # その他のポートにアクセスを許可するCIDR

  MyEC2Instance: # EC2インスタンス 作成
    Type: 'AWS::EC2::Instance'
    Properties:
      ImageId: ami-04e0b6d6cfa432943  # EC2インスタンスに使用するAMIのIDを指定してください
      InstanceType: t2.micro  # EC2インスタンスタイプ
      SecurityGroupIds:
        - !Ref MyEC2SecurityGroup  # セキュリティグループ
      KeyName: OrenoSecurityKey  # キーペア名(今回は作成済)
      IamInstanceProfile: !Ref EC2InstanceProfile
      Tags:
        - Key: Name
          Value: !Ref EC2InstanceName
      UserData:
        Fn::Base64: |
          #!/bin/bash
          # モジュールの最新化
          sudo yum update -y

          # Javaのインストール
          sudo yum install -y java-17

          # CodeDeploy エージェントインストール
          sudo yum install -y ruby
          wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install
          chmod +x ./install
          sudo ./install auto

          # Create a sample service script
          cat > /etc/systemd/system/orenoapplication.service << EOF
          [Unit]
          Description=OrenoApplication
          After=syslog.target

          [Service]
          User=ec2-user
          ExecStart=/usr/bin/java -jar /home/ec2-user/app/OrenoApplication-0.0.1-SNAPSHOT.jar
          WorkingDirectory=/home/ec2-user/app

          [Install]
          WantedBy=multi-user.target
          EOF

          # Enable and start the service
          systemctl daemon-reload

  
  EC2InstanceProfile: # EC2用インスタンスプロファイル
    Type: "AWS::IAM::InstanceProfile"
    Properties:
      Path: "/"
      Roles:
        - !Ref EC2Role
  
  EC2Role: # EC2用ロール
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: S3FullAccessPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 's3:*'
                Resource: '*'


  # S3 バケット
  WebAppS3Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Ref WebAppS3BucketName
    # Webアプリケーションの静的ファイルをホストするためのS3バケットを作成します。
    # 空ではないS3 バケットを削除するには Lambdaでカスタムリソースを使用して中身を空にして削除する必要がある。


  # CodeBuildプロジェクト定義
  CodeBuildProject:
    Type: 'AWS::CodeBuild::Project' # リソースタイプ AWS CodeBuild Project
    Properties:
      Name: WebApplicationPipelineCodeBuild # プロジェクト名
      Description: CodeBuild project for building and deploying web application # プロジェクト説明
      ServiceRole: !GetAtt CodeBuildRole.Arn # CodeBuildが使用するIAMロールARN
      Artifacts: # アーティファクト設定
        Type: S3 # 保存先 S3
        Location: !Sub 'arn:aws:s3:::${WebAppS3Bucket}' # S3バケットのARNを指定
        Packaging: ZIP # アーティファクトのパッケージング ZIP
      Environment: # ビルド環境
        ComputeType: BUILD_GENERAL1_SMALL # コンピューティングタイプ
        Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0 # コンピューティングイメージ
        Type: LINUX_CONTAINER # コンピューティングタイプ
        EnvironmentVariables: # 環境変数
          - Name: S3_BUCKET # 環境変数名 S3バケット
            Type: PLAINTEXT # 環境変数タイプ プレーンテキストで処理
            Value: WebAppS3BucketName # 環境変数値 S3バケット名
      Source: # ソースの設定
        Type: GITHUB # ソースの種類 GitHub
        Location: !Ref GitHubRepoURL # GitHubリポジトリのURL
        GitCloneDepth: 1 # ソースのクローン数
        BuildSpec: buildspec.yml # ソースのビルドスペック

  CodeBuildRole: # CodeBuild IAM ロール定義
    Type: 'AWS::IAM::Role' # リソースタイプ AWS IAM Role
    Properties: # プロパティ設定
      AssumeRolePolicyDocument: # IAMロールのAssumeRolePolicyDocument
        Version: '2012-10-17' # IAMロールポリシーのバージョン
        Statement: # ステートメント
          - Effect: Allow # 許可設定
            Principal: # プリンシパル設定
              Service: codebuild.amazonaws.com # IAMロールのサービス CodeBuild
            Action: 'sts:AssumeRole' # IAMロールのアクション sts:AssumeRole 一時的セキュリティトーン取得
      Policies: # ロールポリシー
        - PolicyName: CodeBuildPolicy # ロールポリシー名
          PolicyDocument: # ロールポリシーのドキュメント
            Version: '2012-10-17' # ロールポリシーのバージョン
            Statement: # ステートメント
              - Effect: Allow # 許可設定
                Action: # 実行許可アクション
                  - 's3:PutObject' # S3へのアップロード
                  - 's3:GetObject' # S3からのダウンロード
                Resource: !Sub 'arn:aws:s3:::${WebAppS3Bucket}/*' # 特定のS3バケットのオブジェクトへのアクセス
              - Effect: Allow # 許可設定
                Action: # 実行許可アクション
                  - 'logs:CreateLogGroup' # ロググループの作成
                  - 'logs:CreateLogStream' # ログストリームの作成
                  - 'logs:PutLogEvents' # ログの記録
                Resource: '*' # すべにアクセス

  CodeDeployApplication: # CodeDeployアプリケーション
    Type: 'AWS::CodeDeploy::Application'
    Properties:
      ApplicationName: CodeDeployApplication

  CodeDeployDeploymentGroup:
    Type: 'AWS::CodeDeploy::DeploymentGroup'
    Properties:
      DeploymentGroupName: CodeDeployDeploymentGroup
      ApplicationName: !Ref CodeDeployApplication
      ServiceRoleArn: !GetAtt CodeDeployRole.Arn  # CodeDeployが使用するIAMロールのARNを指定してください
      DeploymentConfigName: CodeDeployDefault.AllAtOnce  # デプロイメントの構成
      Ec2TagFilters:  # EC2タグを使用してデプロイメントグループをフィルタリング
        - Key: Name
          Value: !Ref EC2InstanceName # EC2インスタンス名(今回は作成済)
          Type: KEY_AND_VALUE # KEY_ONLY: 指定したキーのみ, VALUE_ONLY: 指定した値のみ, KEY_AND_VALUE: 指定したキーと値

  CodeDeployRole: # CodeDeploy用ロール
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: codedeploy.amazonaws.com
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: CodeDeployPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: '*'
                Resource: '*'


  WebAppCodePipeline: # CodePipeline
    Type: 'AWS::CodePipeline::Pipeline'
    Properties:
      ArtifactStore:
        Location: !Ref WebAppS3BucketName
        Type: S3
      RoleArn: !GetAtt CodePipelineRole.Arn
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: ThirdParty
                Provider: GitHub
                Version: 1
              Configuration:
                Owner: '{{resolve:secretsmanager:GitHubSecret:SecretString:Owner}}' # GitHubのリポジトリのオーナー
                Repo: '{{resolve:secretsmanager:GitHubSecret:SecretString:Repo}}'  # GitHubのリポジトリ名
                Branch: main
                OAuthToken: '{{resolve:secretsmanager:GitHubSecret:SecretString:OAuthToken}}'  # GitHubのOAuthトークン
              OutputArtifacts:
                - Name: SourceOutput
          # ソースステージの設定

        - Name: PiplineBuild
          Actions:
            - Name: BuildAction
              ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: 1
              Configuration:
                ProjectName: WebApplicationPipelineCodeBuild
              InputArtifacts:
                - Name: SourceOutput
              OutputArtifacts:
                - Name: BuildOutput
          # ビルドステージの設定

        - Name: PiplineDeploy
          Actions:
            - Name: DeployAction
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CodeDeploy
                Version: 1
              Configuration:
                ApplicationName: CodeDeployApplication
                DeploymentGroupName: CodeDeployDeploymentGroup
              InputArtifacts:
                - Name: BuildOutput
          # デプロイステージの設定

  CodePipelineRole: # CodePipeline用ロール
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: CodePipelinePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
            - Effect: Allow # 許可設定
              Action: # 実行許可アクション
                - 's3:PutObject' # S3へのアップロード
                - 's3:GetObject' # S3からのダウンロード
              Resource: !Sub 'arn:aws:s3:::${WebAppS3Bucket}/*' # 特定のS3バケットのオブジェクトへのアクセス
            - Effect: Allow # 許可設定
              Action: # 実行許可アクション
                - 'logs:CreateLogGroup' # ロググループの作成
                - 'logs:CreateLogStream' # ログストリームの作成
                - 'logs:PutLogEvents' # ログの記録
              Resource: '*' # すべにアクセス
        - PolicyName: PiplineCodeBuildDeployPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'codebuild:StartBuild'
                  - 'codebuild:BatchGetBuilds'
                Resource: !GetAtt CodeBuildProject.Arn
              - Effect: Allow
                Action:
                  - 'codedeploy:CreateDeployment'
                  - 'codedeploy:GetDeployment'
                  - 'codedeploy:GetDeploymentConfig'
                  - 'codedeploy:GetApplicationRevision'
                  - 'codedeploy:RegisterApplicationRevision'
                Resource: '*'

課題

・CloudFormationスタックを削除で、構築したすべての環境が削除されることを想定したていたが、S3にオブジェクトが残っていると削除できない。対応として、カスタムリソースでLambdaを使ってオブジェクトを削除することを検討。
・S3にGitHubのコードをコピーしなくてもそのままBuildしたアーティファクトをS3に保存するようにした方が効率的。できるか検討してみる。

以上

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