0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

実践!AWSでCI/CDやってみる

Posted at

CI/CDとは

開発のプロセスを効率化し、ビルドやテスト、デプロイを自動化する手法です。
これにより、リリースまでの工数削減や手作業によるオペレーションミスを抑止することができます。

主なツールとしては以下のようなものが存在します。

  • GitHub Actions
  • GitLab CI/CD
  • CircleCI
  • AWS Codeシリーズ

CI/CDやってみる

構成

今回は以下のような構成で作成します。
特定リポジトリのmainブランチへPushするとパイプラインが起動し、公開S3バケットへファイルをデプロイする流れとなります。
cicd.png
デプロイの対象としてはHTMLファイルのみとするため、ビルドやテストは省略しています。
必要となる場合は、CodeBuildなどを追加することで実装できます。

検証

事前準備

事前準備として、以下を実施しておきます。

  • GitHubリポジトリを作成し、index.htmlを格納
  • CodeConnectionsにて上記GitHubリポジトリへの権限がある接続を作成
    image.png

環境作成

事前準備が完了したら、S3やCodePipelineなどのAWSリソースを作成していきます。
なお、作成にはCloudFormationを利用します。

テンプレート
AWSTemplateFormatVersion: "2010-09-09"
Description: CICD Demo
Parameters:

  CodeStarConnectionArn:
    Type: String
    Description: ARN of CodeStar Connection
    Default: arn:aws:codestar-connections:ap-northeast-1:123456789012:connection/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

  RepositoryId:
    Type: String
    Description: Code Repository ID
    Default: github-user/repo-name
  
  BranchName:
    Type: String
    Description: Branch Name
    Default: main

Resources:

##############################
# S3 Bucket
##############################

  WebsiteBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'cicd-website-bucket-${AWS::AccountId}'
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false
      WebsiteConfiguration:
        IndexDocument: index.html

  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref WebsiteBucket
      PolicyDocument:
        Statement:
          - Sid: PublicReadForGetBucketObjects
            Effect: Allow
            Principal: "*"
            Action: "s3:GetObject"
            Resource: !Sub 'arn:aws:s3:::${WebsiteBucket}/*'

  ArtifactBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'cicd-artifact-bucket-${AWS::AccountId}'

##############################
# IAM
##############################
    
  CodePipelineServiceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub CodePipeline-Service-Role-${AWS::Region}
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codepipeline.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /

  CodePipelineServiceRolePolicy:
    Type: AWS::IAM::RolePolicy
    Properties:
      RoleName: !Ref CodePipelineServiceRole
      PolicyName: CodePipelineServicePolicy
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - s3:GetObject*
              - s3:GetBucket*
              - s3:List*
              - s3:PutObject*
              - s3:DeleteObject*
              - s3:Abort*
            Resource:
              - !Sub 'arn:aws:s3:::${ArtifactBucket}'
              - !Sub 'arn:aws:s3:::${ArtifactBucket}/*'
          - Effect: Allow
            Action:
              - sts:AssumeRole
            Resource:
              - !GetAtt PipelineSourceRole.Arn
              - !GetAtt PipelineActionRole.Arn


  PipelineSourceRole:
    Type: AWS::IAM::Role
    DependsOn:
      - CodePipelineServiceRole
    Properties:
      RoleName: !Sub CodePipeline-Source-Role-${AWS::Region}
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:role/CodePipeline-Service-Role-${AWS::Region}'
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: CodePipelineSourcePolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject*
                  - s3:GetBucket*
                  - s3:List*
                  - s3:PutObject*
                  - s3:DeleteObject*
                  - s3:Abort*
                Resource:
                  - !Sub 'arn:aws:s3:::${ArtifactBucket}'
                  - !Sub 'arn:aws:s3:::${ArtifactBucket}/*'
              - Effect: Allow
                Action:
                  - codestar-connections:UseConnection
                Resource:
                  - !Sub 'arn:aws:codeconnections:${AWS::Region}:${AWS::AccountId}:connection/*'
      Path: /

  PipelineActionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub CodePipeline-Action-Role-${AWS::Region}
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:role/CodePipeline-Service-Role-${AWS::Region}'
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: CodePipelineActionPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject*
                  - s3:GetBucket*
                  - s3:List*
                  - s3:PutObject*
                  - s3:DeleteObject*
                  - s3:Abort*
                Resource:
                  - !Sub 'arn:aws:s3:::${ArtifactBucket}'
                  - !Sub 'arn:aws:s3:::${ArtifactBucket}/*'
                  - !Sub 'arn:aws:s3:::${WebsiteBucket}'
                  - !Sub 'arn:aws:s3:::${WebsiteBucket}/*'
      Path: /

##############################
# CodePipeline
##############################

  CICDPipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      Name: cicd-s3-pipeline
      PipelineType: V2
      RoleArn: !GetAtt CodePipelineServiceRole.Arn
      ArtifactStore:
        Type: S3
        Location: !Ref ArtifactBucket
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              RunOrder: 1
              RoleArn: !GetAtt PipelineSourceRole.Arn
              ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: CodeStarSourceConnection
                Version: '1'
              Configuration:
                ConnectionArn: !Ref CodeStarConnectionArn
                FullRepositoryId: !Ref RepositoryId
                BranchName:  !Ref BranchName
              OutputArtifacts:
                - Name: SourceOutput
        - Name: Deploy
          Actions:
            - Name: DeployAction
              RunOrder: 1
              RoleArn: !GetAtt PipelineActionRole.Arn
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: S3
                Version: '1'
              Configuration:
                BucketName: !Ref WebsiteBucket
                Extract: 'true'
              InputArtifacts:
                - Name: SourceOutput

※利用する際はスタック作成時のパラメータに事前準備で作成したものを入力ください。

下図のようにCREATE_COMPLEATEと表示されたら正常に作成完了です。
image.png

リソースの作成ができたら、実際にWebブラウザからアクセスしてみます。
今回は事前準備の際に、以下のindex.htmlファイルを格納していますので、Hello, World!と表示されるはずです。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>cicdデモ</title>
</head>
<body>
    <h1>Hello, World!</h1>
</body>
</html>

なお、ブラウザに入力するURLは作成されたS3バケットの プロパティ > 静的ウェブサイトホスティングから確認が可能です。
image.png

確認してみると、想定通りにWebページが表示されました!
image.png

CI/CDの確認

環境の作成ができたところで、任意のエディタからindex.htmlを編集し、Webページの表示が変更されることを確認していきましょう。
Hello, World!としていた箇所をHello, CI/CD!に変更し、mainブランチへプッシュします。
image.png

Webブラウザからアクセスすると、変更した箇所が反映されていました!
image.png

環境削除

検証用に作成した環境はCloudFormationのスタック削除から実施します。
S3にファイルが格納されたままだと削除時にエラーになるため、事前に空にしておきましょう。

まとめ

通常であれば、今回のケースであればindex.htmlを変更してGitHubに同期しS3にも手動でアップロード…といった手順が必要になります。
1ファイルならまだよいですが、ファイルが多ければ多いほど面倒です。
さらに、ビルドやテストも実行するとなるとその都度工数が発生します。
CI/CD環境を整えておくと、工数が短縮され、手作業でのミスも抑止されるため進んで導入していきたいなと感じました。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?