LoginSignup
1
1

一番簡単なCodeBuild

Posted at

はじめに

CodeBuildを触ってみたいと思い、ハンズオンなど探してみたのですが、CodePipelineの例ばかりでした。
そのためCodeBuildをメインとして自身で手を動かした内容をまとめておきました。

概要

本記事では以下の事をやっています。

  • CodeBuildの実行
    • 取り扱うファイルを格納するため、CodeCommitを用意します
  • CodeBuildで利用するインスタンスから、ファイルをS3に格納
    • 格納用のS3バケットを用意します

参考

Level0:動かすだけ

まず、CodeCommitを作ります。以下は作成するCFnテンプレートですが、コンソールから作成してもよいです。

createCodeCommit.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyCodeCommitRepo:
    Type: AWS::CodeCommit::Repository
    Properties:
      RepositoryName: forCodeBuild

作成したCodeCommitに、以下のbuildspec.ymlファイルをコミットします。

buildspec.yml
version: 0.2

phases:
  build:
    commands:
      - echo "Hello, CodeBuild!"
      - echo "This is a sample build."

今回は単純なので、コンソールで操作しています。コンソールからファイルをアップしたり、新規で作成することができます。
最初に作成されるブランチ名はmainになります。
image.png
image.png

その後、CodeBuildのプロジェクトを作成します。
image.png

ソースは先ほど作成し、コミット時に作られたmainブランチを指定します。
image.png

環境も適当に指定します。
image.png

ロールもコンソールで作ってもらえます。
image.png

ビルド仕様は、さっきコミットしたファイルを使います。
image.png

バッチ設定、アーティファクトは何も設定しません。
image.png

ログは、buildspec.ymlでのechoを見るために、CloudWatchを使います。グループ名、ストリーム名は空で問題ないです。
image.png

これで作成します。
image.png

作成後、ビルドを開始します。
image.png

ビルドログに色々出てきます。buildspec.ymlのechoで指定した文字列が出力されているか確認します。
image.png

問題なければ、ステータスが成功になっているはずです。
image.png

CFnで作る

(ほぼ)コンソールでやってきたことを、CFnテンプレートで作成しました。
以下のリソースを作成するCFnテンプレートになります。

  • CodeCommitのリポジトリ
  • CodeBuild用のCloudWatchロググループ
  • CodeBuild用のIAMロール
    • ロググループに出力権限付与
    • リポジトリからPULL権限付与
    • コンソールが作成する際に付与される以下の権限はつけない
      • CodePipelineのバケット用のポリシー
      • レポート用のポリシー
  • CodeBuildプロジェクト
    • CodeCommitリポジトリのmainブランチを見ています
クリックで表示
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  ProjectName:
    Type: String
    Default: testProjectByCfn
  RepositoryName:
    Type: String
    Default: forCodeBuildByCfn

Resources:
  MyCodeCommitRepo:
    Type: AWS::CodeCommit::Repository
    Properties:
      RepositoryName: !Ref RepositoryName

  LogGroupForCB:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/codebuild/${ProjectName}"
      RetentionInDays: 3653   # 未指定時は「失効しない」

  RoleForCB:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codebuild.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: writeLogs
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource:
                  - !GetAtt LogGroupForCB.Arn
                  - !Join
                    - ':'
                    - - !GetAtt LogGroupForCB.Arn
                      - '*'
        - PolicyName: pullCodeCommit
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - codecommit:GitPull
                Resource:
                  - !GetAtt MyCodeCommitRepo.Arn
        # CodePipelineのバケット用のポリシーは作成しない
        # レポート用のポリシーも作成しない

  CBProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: !Ref ProjectName
      ServiceRole: !GetAtt RoleForCB.Arn
      Artifacts:
        Type: no_artifacts
      Environment:
        Type: LINUX_CONTAINER
        ComputeType: BUILD_GENERAL1_SMALL
        # 以下の Image identifier を参照
        ## https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html
        Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0
      Source:
        Type: CODECOMMIT
        Location: !GetAtt MyCodeCommitRepo.CloneUrlHttp
        GitCloneDepth: 1 # 指定しないと、フル
      SourceVersion: refs/heads/main
      LogsConfig:
        CloudWatchLogs:
          Status: ENABLED
        S3Logs:
          Status: DISABLED

作成後はCodeCommitのmainブランチにbuildspec.ymlをコミットし、プロジェクトを実行することで、コンソール時と同じ結果が得られるはずです。

Level1:チェックを入れる

buildspec.ymlの中身を書き換えて、一緒にコミットするファイルの中身に特定の文字列があるかをチェックするようにします。

チェックするファイルを以下のように追加します。

sample.txt
hogehoge
mogemoge
togetoge

チェック処理はgrepを使ってみます。

buildspec.yml
version: 0.2

phases:
  build:
    commands:
      - echo "Hello, CodeBuild!"
      - echo "This is a sample build."
+     - grep -q "mogemoge" sample.txt

CodeCommitに追加後、プロジェクトを実行します。特に問題なく成功するはずです。
image.png

わざと失敗するため、sample.txtの中身を書き換えてコミットします。

sample.txt
hogehoge
pogepoge
togetoge

実行すると失敗と出ます。
image.png
ログメッセージは以下のようになっています。

Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: grep -q "mogemoge" sample.txt. Reason: exit status 1

エラーの理由をメッセージで出すため、このようにしてみました。

buildspec.yml
version: 0.2

phases:
  build:
    commands:
      - echo "Hello, CodeBuild!"
      - echo "This is a sample build."
-     - grep -q "mogemoge" sample.txt
+     - |
+       if ! grep -q "mogemoge" sample.txt; then
+         echo "Test failed: 'mogemoge' not found in sample.txt"
+         exit 1
+       fi

以下のように、指定したメッセージを出してエラーにしてくれます。

Test failed: 'mogemoge' not found in sample.txt

Level2:S3に出力する

次は、CodeBuildで扱ったファイルを、S3に置いてみます。

出力用バケットを作成

以下のCFnテンプレートでバケットを作成します。

createS3ForCodebuild.yaml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "out-artifacts-ap-northeast-1-${AWS::AccountId}"

CodeBuildに設定

作成したCodeBuildに、コンソールから出力先を指定できます。
image.png

image.png

コンソールで以下のチェックを入れると、使っているIAMロールに出力先バケットへの権限を付与してくれます。
image.png

ポリシーに以下が追加されていました。

        {
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::out-artifacts-ap-northeast-1-123456789012",
                "arn:aws:s3:::out-artifacts-ap-northeast-1-123456789012/*"
            ],
            "Action": [
                "s3:PutObject",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation"
            ]
        },

buildspec.ymlに記載

出力する旨をbuildspec.ymlに記載します。

buildspec.yml(最後に追記)
artifacts:
  files:
    - '**/*'

実行すると、指定したバケットに保存されます。再実行の際は上書きされました。
image.png

CFnで作る

先のCFnテンプレートに、以下を追加したものになります。

  • S3バケット
  • バケットへのアクセス権限
    • IAMロールに
  • Artifactsセクション

先の環境を作成したCFnスタックを、以下で更新します。

クリックで表示
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  ProjectName:
    Type: String
    Default: testProjectByCfn
  RepositoryName:
    Type: String
    Default: forCodeBuildByCfn

Resources:
  MyCodeCommitRepo:
    Type: AWS::CodeCommit::Repository
    Properties:
      RepositoryName: !Ref RepositoryName

  MyS3Bucket:
    Type: AWS::S3::Bucket

  LogGroupForCB:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/codebuild/${ProjectName}"
      RetentionInDays: 3653   # 未指定時は「失効しない」

  RoleForCB:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codebuild.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: writeLogs
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource:
                  - !GetAtt LogGroupForCB.Arn
                  - !Join
                    - ':'
                    - - !GetAtt LogGroupForCB.Arn
                      - '*'
        - PolicyName: pullCodeCommit
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - codecommit:GitPull
                Resource:
                  - !GetAtt MyCodeCommitRepo.Arn
        - PolicyName: putBucketArtifacts
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - s3:PutObject
                  - s3:GetBucketAcl
                  - s3:GetBucketLocation
                Resource:
                  - !GetAtt MyS3Bucket.Arn
                  - !Join
                    - '/'
                    - - !GetAtt MyS3Bucket.Arn
                      - '*'

  CBProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: !Ref ProjectName
      ServiceRole: !GetAtt RoleForCB.Arn
      Artifacts:
        Type: S3
        Location: !Ref MyS3Bucket
        EncryptionDisabled: true
      Environment:
        Type: LINUX_CONTAINER
        ComputeType: BUILD_GENERAL1_SMALL
        # 以下の Image identifier を参照
        ## https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html
        Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0
      Source:
        Type: CODECOMMIT
        Location: !GetAtt MyCodeCommitRepo.CloneUrlHttp
        GitCloneDepth: 1 # 指定しないと、フル
      SourceVersion: refs/heads/main
      LogsConfig:
        CloudWatchLogs:
          Status: ENABLED
        S3Logs:
          Status: DISABLED

Level3:作成したファイルだけ置く

先ほどは、CodeCommitからPULLしたファイルをすべてS3に置きました。今度はチェック後、そのファイルを元に新しくファイルを作成しS3に置く、というのをやってみます。
sample.txt内の文字列をすべて大文字にしてsample2.txtを作り、そのファイルだけをS3に置くようにします。

buildspec.yml
version: 0.2

phases:
  build:
    commands:
      - echo "Hello, CodeBuild!"
      - echo "This is a sample build."
      - |
        if ! grep -q "mogemoge" sample.txt; then
          echo "Test failed: 'mogemoge' not found in sample.txt"
          exit 1
        fi
+     - cat sample.txt | tr [:lower:] [:upper:] > sample2.txt

artifacts:
  files:
-   - '**/*'
+   - sample2.txt

先ほどのファイルが残っている場合は、S3を空にしておいてから実行します。
image.png
中身もちゃんと大文字になっています。
image.png

buildセクションで失敗するようにしていた場合、ファイルは何も変更ありませんでした。ちゃんと止まるようです。

片付け

以下のリソースが作成されていますので、不要であれば削除してください。CFnテンプレートで作成した場合も、S3バケットを空にした後にスタックの削除を行ってください。

  • S3
    • バケットを空にしてから
  • CodeCommit
  • CodeBuild
  • IAMロール・ポリシー
    • CodeBuildプロジェクト作成時に自動作成されたもの
  • Cloudwatchロググループ

おわりに

今回はCodeBuildの初歩の初歩を自分なりにまとめて記事にしました。
私のように「CodeBuildだけ試しに使ってみたい」という方のお役に立てれば幸いです。

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