AWS CodePipelineを使ったSAMアプリケーションのCI/CD環境構築(前編)

AWS

はじめに

AWSサービスを利用し、SAMアプリケーションのCI/CD環境を構築してみます。

前編でCodeCommitとCodeBuildの構築、
後編でCodePipeline構築とSlack通知設定を行います。

実現すること

  • リポジトリにPushすると自動でビルド、デプロイを実行する
  • ビルド、デプロイ結果をSlackに通知

利用するAWSサービス

サービス名概要
AWS CodeCommitリポジトリサービス
AWS CodeBuildビルドサービス
AWS CodePipeline・継続的デリバリーサービス
・CodeCommitの通知を受けとりビルドとデプロイを実行
Amazon SNSビルド、デプロイ結果をAWS Chatbotに連携
AWS ChatbotSNSからの通知をSlackに連携

前提

ローカルマシンにPython, AWSCLIがインストール済であること

AWS CodeCommit

AWS CodeCommitの概要

2024.9月現在では新規アカウントでのサービス受付が停止となっています。

  • gitリポジトリをホストするサービス
  • IAMによるユーザ管理
  • 使用量に応じた課金で非常に安価に利用可能。無料枠も多い
  • CodeCommitの料金

AWS CodeCommitの構築

ソースを格納するリポジトリをCodeCommitで作成します。リポジトリ構築はリポジトリ名を指定する程度なので説明は割愛します。以下を参照ください。
AWS CodeCommit の使用を開始する

構築用のCloudFormationは以下になります。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  codecommit-sample

Resources:
  MyRepo:
    Type: AWS::CodeCommit::Repository
    Properties:
      # リポジトリ名
      RepositoryName: MyDemoRepo
      RepositoryDescription: Demo repository

AWS CodeCommit用IAMユーザの作成と接続

CodeCommitへの接続方法はSSHやHTTPS,HTTPS(GRC)がありますが、
今回は管理が容易なHTTPS(GRC)を利用します。
HTTPS(GRC)を利用するとgit認証情報が不要となり、IAM認証情報だけで接続出来ます。

■手順

  • CodeCommit接続用IAMユーザの作成
    • 任意のユーザを作成し、必要な権限を付与する。今回は「AWSCodeCommitPowerUser」のポリシーを付与。
    • アクセスキーを有効にする
  • git-remote-codecommitのインストール
    •  GRCを使った接続に必要なツールを以下コマンドでインストール
    •  pip install git-remote-codecommit
  • リポジトリのクローンを作成
    • git clone codecommit::ap-northeast-1://MyDemoRepo

SAMアプリケーションをリポジトリに追加

ビルド&デプロイのテスト用に簡単なSAMアプリケーションを作成します。
今回はsam initで作成した以下のファイルをそのまま利用するので、
下記の構成のままCodeCommitリポジトリのルートに追加します。

├── hello_world
│   └── app.py
├── samconfig.toml
└── template.yaml

SAMアプリケーションの template.yaml、samconfig.tomlは以下のような内容です。
CloudFormationテンプレートをアップロードするS3バケットが
必要なので先に作成しておき、samconfig.tomlの「s3_bucket」で指定して下さい。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  webapi sample

Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "dev-demo-myapp"
s3_bucket = "your-s3-backet-name"
s3_prefix = "dev-demo-myapp"
region = "ap-northeast-1"
capabilities = "CAPABILITY_IAM"
disable_rollback = true
image_repositories = []

AWS CodeBuild

AWS CodeBuildの概要

Jenkinsのような機能を提供するビルドサービスです。
以下のような特徴があります。

・ソースコードのコンパイル、テスト実行、パッケージの作成をサポート
・複数プロセスの並列実行が可能
・自動スケーリング
・利用した分のみ課金
・Dockerを利用しカスタムビルド環境も作成できる

ビルド環境はJava、Python、Node.js、Ruby、Go、.NET Coreなど主要なものは準備されています。構築はとても簡単で使った分だけ課金で高スペックサーバが管理不要で利用できるのでオススメのサービスです。

ビルド仕様 (buildspec) ファイルの作成

CodeBuildで利用するランタイムやビルドコマンドなどはbuildspecファイルに記載します。
今回はランタイムにPython3.8を利用し、SAM CLIのUpdateを追加しています。
作成したbuildspec.yamlはCodeCommitリポジトリのルートに追加します。

version: 0.2

phases:
  install:
    runtime-versions:
      python: 3.8
    commands:
      # Upgrading SAM CLI to latest version
      - pip3 install --upgrade aws-sam-cli
  pre_build:
    commands:
      - sam --version
      - sam validate
  build:
    commands:
      - echo SAM Application Build started on `date`
      - sam build
      - sam deploy --no-confirm-changeset --no-fail-on-empty-changeset
  post_build:
    commands:
      - echo Build completed on `date`

AWS CodeBuildの構築

以下の内容で構築します。
・ソースプロバイダ(ビルドを行う対象)に作成したAWS CodeCommitのリポジトリを指定
・ビルド環境はマネージド型の最小スペックで、OSにはAmazonLinux2を指定
・buildspecはデフォルトでリポジトリ直下のファイルが参照されるので明示的な指定はしない
・アーティファクトは無し
・CloudWatchLogsは有効化

CodeBuildでSAMアプリケーションをデプロイする場合は利用する様々なサービスのIAM権限が必要になります。
今回は「MyCodePipelineServiceRole」で作成していますが、必要なサービス権限があれば追加してください。

サンプルではIAM権限の付与についてリソース制限はかけていませんが本番環境ではリソースも絞りましょう。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  codebuild-sample

Resources:
  MyCodePipelineServiceRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: "my-codepipeline-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codepipeline.amazonaws.com
                - codebuild.amazonaws.com
            Action: "sts:AssumeRole"
      Path: /
      Policies:
        - PolicyName: my-pipeline-policy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "s3:GetBucketAcl"
                  - "s3:PutObject"
                  - "s3:GetBucketLocation"
                  - "s3:GetObject"
                  - "s3:GetObjectVersion"
                Resource: "*"
              - Effect: Allow
                Action:
                  - "codecommit:CancelUploadArchive"
                  - "codecommit:GetBranch"
                  - "codecommit:GetCommit"
                  - "codecommit:GetUploadArchiveStatus"
                  - "codecommit:UploadArchive"
                  - "codecommit:GitPull"
                Resource: "*"
              - Effect: Allow
                Action:
                  - "ecr:DescribeImages"
                Resource: "*"
              - Effect: Allow
                Action:
                  - "codebuild:BatchGetBuilds"
                  - "codebuild:BatchPutCodeCoverages"
                  - "codebuild:BatchPutTestCases"
                  - "codebuild:CreateReport"
                  - "codebuild:CreateReportGroup"
                  - "codebuild:StartBuild"
                  - "codebuild:UpdateReport"
                Resource:
                  - !Sub "arn:aws:codebuild:*:${AWS::AccountId}:*"
              - Effect: Allow
                Action:
                  - "iam:AttachRolePolicy"
                  - "iam:CreateRole"
                  - "iam:DeletePolicy"
                  - "iam:DeleteRole"
                  - "iam:DetachRolePolicy"
                  - "iam:GetAccountSummary"
                  - "iam:GetLoginProfile"
                  - "iam:GetRole"
                  - "iam:GetRolePolicy"
                  - "iam:List*"
                  - "iam:PassRole"
                Resource: "*"
              - Effect: Allow
                Action:
                  - "cloudformation:*"
                Resource: "*"
              - Effect: Allow
                Action:
                  - "logs:CreateLogGroup"
                  - "logs:CreateLogStream"
                  - "logs:DeleteLogGroup"
                  - "logs:DeleteLogStream"
                  - "logs:DescribeLog*"
                  - "logs:FilterLogEvents"
                  - "logs:PutLogEvents"
                Resource: "*"
              - Effect: Allow
                Action:
                  - "lambda:*"
                  - "apigateway:*"
                Resource: "*"

  MyCodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: myProjectName
      Description: A description about my project
      ServiceRole: !GetAtt MyCodePipelineServiceRole.Arn
      Source:
        Type: CODECOMMIT
        Location: https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/YourRepositoryName
      Artifacts:
        Type: no_artifacts
      Environment:
        Type: LINUX_CONTAINER
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
      LogsConfig:
        CloudWatchLogs:
          GroupName: MyCodeBuildProjectLogs
          Status: ENABLED

これでビルド環境が出来ました。
後編ではこのビルド環境をCodePipleneで自動実行するようにしますが、
まずは手動でビルドが成功するかを確認しておきます。

AWSコンソールで「CodeBuild」を開き、作成したビルドプロジェクトを
選択し「ビルドを開始」ボタンを押下します。

ビルドが無事完了し、SAMアプリケーションがデプロイされればOKです。

以上

タイトルとURLをコピーしました