Chapter 07

CloudFormation-api

sotaro116
sotaro116
2022.10.27に更新

本セクションの目標

  • CloudFormation の概要を理解すること
  • CodePipelineをcloudformationを使用し作成できること

今回実施すること

  • CloudFormation のテンプレートを作成する
  • テンプレートをマネジメントコンソールからアップロードする
  • API 側で使用する AWS サービスのテンプレートをパイプラインで反映する

CloudFormation とは

IaC (Infrastructure as Code)
インフラ構成をコードベースで管理することができる。

メリット

  • 一元的に構成を確認することができる
  • ソースコードと同様にバージョン管理をすることができる

特に "再現性" が非常に重要

他のプロジェクトのインフラ構成を参考にしたい時に、テンプレートがあれば簡単に自分のプロジェクトに応用することができる

https://qiita.com/tearoom6/items/49354efc105e53a78c80

概要

  • 別資料(【新人研修】CloudFormation編)に記載
  • S3(aws-training-digidept-work-dev)

https://aws.amazon.com/jp/blogs/news/webinar-bb-aws-cloudformation-2020/

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html

ハンズオン

CodeCommit リポジトリの作成

  1. CodeCommit コンソールを開く。
  2. リージョンが東京 (ap-northeast-1) であることを確認する。違う場合、東京に設定する。
  3. ▼ ソース > リポジトリ ページで「リポジトリを作成」を選択。
  4. リポジトリ名に任意の名前を入力。(今回は API 資源のリポジトリを作成するため training-api-{グループ番号}-
  5. 「作成」を選択。

CodeCommit リポジトリの引き込み

  1. CodeCommit コンソールを開く。
  2. ▼ ソース > リポジトリ ページの右側にある「URL のクローン」から、上記で作成したリポジトリの「HTTPS」を選択。Git リポジトリのクローンを作成するアドレスがクリップボードにコピーされる。
  3. ターミナルまたはコマンドラインで、ローカルリポジトリを保存するディレクトリに移動する。(例:/work)
  4. 次のコマンドを実行してリポジトリをローカルにクローンする。その際、認証情報を聞かれるため、IAM ユーザーのアクセスキーとシークレットキーを入力する。
    git clone codecommit::ap-northeast-1://317076571640@training-api-{グループ番号}
    
  5. 認証に成功すると、ローカルに training-api-{グループ番号}- という名前のディレクトリが作成される。

CloudFormation テンプレートファイルの作成と CodeCommit リポジトリへの資源追加

  1. 上記で作成したディレクトリに、以下の構成となるよう資源を配置していく。
    aws-training-digidept-work-devバケット内にもtraining-api.zipとして資源を格納しています。
/
├ src/
│ └ function/
│  └ Scan/
│   └ index.js                  ...手順1
├ test/
│ └ function/
│  └ Scan/
│   └ index.spec.ts             ...手順1
├ .gitignore                    ...手順2
├ buildspec.yaml                ...手順3
├ demo-digi-api-template.yaml   ...手順4
├ jest.config.js                ...手順5
├ package-lock.json             ...手順6
├ package.json                  ...手順7
└ template-parameter-it.json  ...手順8
  1. Lambda 資源とそのテスト資源を、index.js index.spec.ts ファイルとして上記ディレクトリに配置する。
index.js
// AWSの各サービスを利用するためのライブラリを宣言
const AWS = require('aws-sdk')
// DynamoDBを操作するための変数を宣言
const docClient = new AWS.DynamoDB.DocumentClient()

exports.handler = async (event) => {
  // DynamoDBの指定のテーブルからデータを全件取得するためのメソッドで必要な引数を定義
  const scanItemPayload = {
    TableName: 'process.env.TABLE_NAME' // テーブル名はそれぞれの名前に変更する
  }
  // DynamoDBにアクセス
  const dynamoDBResponse = await docClient.scan(scanItemPayload).promise()

  // 取得した項目をLambdaのbodyに入れてレスポンス
  const response = {
    statusCode: 200,
    body: JSON.stringify(dynamoDBResponse),
    headers: {
      'Access-Control-Allow-Origin': '*'
    }
  }
  return response
}

index.spec.ts
const expectDBResponse = {
  Items: [
    {
      id: '001',
      name: 'タスク1'
    }
  ],
  Count: 1,
  ScannedCount: 1
}
const scanStub = jest.fn().mockResolvedValue(expectDBResponse)
const scanSpy = jest.fn().mockReturnValue({
  promise: scanStub
})
const DocumentClientConstructor = jest.fn().mockReturnValue({
  scan: scanSpy
})
jest.mock('aws-sdk', () => {
  return {
    DynamoDB: {
      DocumentClient: DocumentClientConstructor
    }
  }
})
import { APIGatewayProxyResult } from 'aws-lambda'
import { handler } from '../../../src/function/Scan/index'

describe('正常系のテスト', () => {
  let response: APIGatewayProxyResult
  beforeEach(async () => {
    const event = {}
    //@ts-ignore
    response = await handler(event)
  })

  it('DynamoDBのscanメソッドが実行されていること', () => {
    const expectedParams = {
      TableName: 'process.env.TABLE_NAME'
    }
    expect(scanSpy).toHaveBeenCalledWith(expectedParams)
  })
  it('ステータスが200でDBの値を入れてレスポンスしていること', () => {
    const expectedResponse = {
      statusCode: 200,
      body: JSON.stringify(expectDBResponse),
      headers: {
        'Access-Control-Allow-Origin': '*'
      }
    }
    expect(response).toEqual(expectedResponse)
  })
})

  1. 以下のファイルを.gitignoreとしてルートディレクトリに作成する。
node_modules
  1. 以下のファイルをbuildspec.ymlとしてルートディレクトリに作成する。
buildspec.yml
version: 0.2
# 各項目の詳細
# https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html
phases:
  # codebuildの環境で実施するコマンドがある場合に記述(ランタイムのバージョン指定)
  install:
    runtime-versions:
      nodejs: 12
  # build前のコマンド
  pre_build:
    commands:
      # echoコマンド ただの標準出力でログに'pre build'が表示されるだけ
      - echo 'pre build'
      - ls
      # aws cliのバージョンを確認するコマンド
      - aws --version
  # buildコマンド
  build:
    commands:
      - echo 'Entering build phase'
      # CDコマンド ただのCDコマンドだが、CodeBuildは元からいくつかの変数を持っている CODEBUILD_SRC_DIRはbuildspecファイルがある階層と思って良い
      # https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-env-ref-env-vars.html
      - cd ${CODEBUILD_SRC_DIR}
      - echo 'root modules install'
      # 「npm i」はpackage.jsonを見てパッケージをインストールする。「npm ci」はpackage-lock.jsonを見てパッケージをインストールする。(ただし、package.jsonとpackage-lock.jsonの記載に差異があれば失敗する)
      # ここまでの記述でCodeBuildというPCにjavascriptで書かれたコードを実行させるための環境が構築された
      # https://docs.npmjs.com/cli/v7/commands/npm-ci
      - npm ci
      # テストの実行コマンド package.jsonのscriptに記載してあるコマンドを実行している。テストそのものについては割愛
      # テストコードを実行し、開発環境で動いたものがCodeBuildの環境でも動くことを保証する。
      - npm run test
      # コンパイルコマンド typescript => javascriptにコンパイルするコマンド
      # - npm run tsc
      # awsコマンド packageで、第一引数は生成するファイルの名前、第2引数はアーティファクトの出力先...と書いてあるが噛み砕いて言うとsrcとかxxxtemplate.yamlとかpackage.jsonとか
      # buildspec.yamlが存在する階層のフォルダとファイルをzipで固めたものがアーティファクト
      # https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudformation/package.html
      #
      # packageコマンドで出力されたdemo-digi-api-template.yamlファイルはローカルで持っているyamlファイルと何が違うのか確認するとわかりやすい
      - aws cloudformation package --template-file demo-digi-api-template.yaml --output-template-file demo-digi-api-template-output.yaml --s3-bucket aws-training-digidept-work-dev
      - cat demo-digi-api-template.yaml
# CodeBuildがoutputするもの(S3に出力されるアーティファクトとは異なる)
artifacts:
  type: zip
  files:
    # aws cloudformation packageコマンドで生成されたyamlファイル
    - demo-digi-api-template-output.yaml
    # 同じ階層に配置されたjsonファイル
    - template-parameter-${Env}.json


  1. 以下のファイルをdemo-digi-template.yamlとしてルートディレクトリに作成する。
demo-digi-api-template.yaml
# 現時点で唯一有効なバージョン
# https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/format-version-structure.html
AWSTemplateFormatVersion:
  "2010-09-09"
  # SAM構文を記述するために必要な記述
  # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/transform-aws-serverless.html
  # SAMとは? CloudFormationを拡張する、サーバーレスアプリケーションを定義出来るテンプレート
  # https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/what-is-sam.html
  # CloudFormationとは? CodeでAWSのサービス(インフラ)を定義することが出来るサービス。AWSをポチポチしなくて良いし、Codeを書き換えることで更新出来るなどクラウドサービスを管理しやすい。
  # SAMはCloudFormationと何が違うの?
  # ⇒ SAMはあくまでCloudFormationの拡張(CloudFormationの一部という認識で良い)
  # ⇒ 記述量が少なくて住む。cloudformationのテンプレートを確認すると記述量に差があることがわかる。(IAM Roleとか下で記述するGlobalsとか)
  # ⇒ local環境でlambdaやdynamoを立ち上げることが出来る(...が設定が必要だったりしてデジ開でやってるところはなさそう)
Transform: AWS::Serverless-2016-10-31
Description:
  demo-digi-api template

  # 変数の型設定 このtemplate内で利用出来る変数を記述 実態はtemplate-parameter.jsonから取得(CodeDeployでCreateChangeSetのフェーズで設定)
Parameters:
  Env:
    Type: "String"
  Prefix:
    Type: "String"
  ApiStage:
    Type: "String"
  TableName:
    Type: "String"
  LambdaRole:
    Type: "String"
  CloudWatchRole:
    Type: "String"
    # Conditionsによる環境の制御 IsItはEnvがITの時にtrueになるよ という記述
    # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html
Conditions:
  IsIt:
    !Equals [!Ref Env, it]
    # このtemplateで使うlambdaで共通の設定を行う事ができる(run timeの他にメモリやEnvironmentで定義している環境変数など)
    # https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-specification-template-anatomy-globals.html
Globals:
  Function:
    Runtime: nodejs14.x
    Handler: index.handler
    Tracing: Active
    Environment:
      Variables:
        ENV: !Ref Env
        TZ: "Asia/Tokyo"
    # AWS上のサービスの定義
Resources:
  # template内での名前
  ApiGwAccountConfig:
    # Typeでどのリソースを作るか指定
    # AWS::ApiGateway::Account: https://docs.aws.amazon.com/en_us/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-account.html
    # リソース定義 cfn: https://docs.aws.amazon.com/en_us/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html
    # リソース定義 sam: https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-specification-resources-and-properties.html
    Type: "AWS::ApiGateway::Account"
    # CloudwatchLogsへの書き込み権限のあるロールを指定する。
    Properties:
      CloudWatchRoleArn: !Ref CloudWatchRole
    # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html
    # CloudWatchRoleArn: !ImportValue APIGatewayPushToCloudWatchLogsRoleArn

    #######################################
    ####### API Gateway Definition ########
    #######################################
    # APIGateway
  DemoDigiAPI:
    # APIGatewayの設定
    # https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-resource-api.html
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref ApiStage
      # エンドポイントタイプを設定 EDGEは地理的一番近いエンドポイントが叩かれるように設定。
      # https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-api-endpoint-types.html
      EndpointConfiguration: EDGE
      # 各resourceに対してhttpmethodを決められるが、今回は全てのresourceに対して何も制限しない設定
      # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-apitgateway-stage-methodsetting.html
      MethodSettings:
        - DataTraceEnabled: false
          LoggingLevel: "INFO"
          ResourcePath: "/*"
          HttpMethod: "*"
      Cors:
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"
        # AllowHeaders: !If [IsIt, "'*'", !Ref "AWS::NoValue"]
        # AllowOrigin: !If [IsIt, "'*'", !Ref "AWS::NoValue"]

    ####################################
    #### Lambda Function Definition ####
    ####################################
  Scan:
    # lambdaの設定
    # https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-resource-function.html
    Type: "AWS::Serverless::Function"
    # lambda関数自体の設定
    Properties:
      # lambda関数になるファイルの場所(Uri)
      # ただし aws cloudformation package後に書き換わる https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-cli-package.html
      CodeUri: src/function/Scan
      FunctionName: !Sub ${Prefix}scan-${Env}
      Description: "Scan"
      MemorySize: 128
      Timeout: 30
      Role: !Ref LambdaRole
      Environment:
        Variables:
          TABLE_NAME: !Ref TableName
      # 関数に対するトリガーの設定
      # https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-property-function-eventsource.html
      Events:
        # RestApiの構築 (Api⇒RestApi, HttpApi⇒HttpApi) それぞれの違いはこちら https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/http-api-vs-rest.html
        # https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-property-function-api.html
        Api:
          Type: Api
          Properties:
            # APIの叩くパス
            Path: /item
            # APIを叩くhttpメソッド
            Method: get
            # ApiGatewayの設定
            RestApiId:
              Ref: DemoDigiAPI

    #------------------------------------------------------
    # DynamoDB
    #------------------------------------------------------
  DemoDigiTable:
    # DynamoDBの設定
    # https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-property-function-dynamodb.html
    Type: AWS::DynamoDB::Table
    # テーブル定義
    # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html
    Properties:
      # テーブルの項目
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      # テーブルのキー(Oracleなど他のDBではプライマリーキーと言ったりするが、DynamoDBではパーティションキーと言う)
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      TableName: !Ref TableName
      # データベースに対する読み取り、書き込みの課金方法の定義
      # プロビジョニングモードとオンデマンドモードがある。オンデマンド(PAY_PER_REQUEST)が無制限、プロビジョニング(PROVISIONED)は
      # ProvisionedThroughputでReadCapacityUnitsとWriteCapacityUnitsの数を指定する。 (AWSの資格試験とかで絶対出るやつ)
      # https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html
      BillingMode: PAY_PER_REQUEST
      # ポイントインタイムリカバリを有効にする設定
      # ポイントインタイムリカバリとは? 過去35日間であればどのタイミングでもリカバリ出来るというもの。
      # https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/PointInTimeRecovery.html
      PointInTimeRecoverySpecification:
        PointInTimeRecoveryEnabled: true
  1. 以下のファイルをjest.config.jsとしてルートディレクトリに作成する。
jest.config.js
module.exports = {
  roots: ["<rootDir>"],
  testMatch: ["**/?(*.)(spec|test).ts"],
  transform: {
    "^.+\\.(ts)$": "ts-jest",
  },
};

  1. 以下のファイルをpackage-lock.jsonとしてルートディレクトリに作成する。

    コード量が多いため省略

  2. 以下のファイルをpackage.jsonとしてルートディレクトリに作成する。

package.json
{
  "name": "demo-digi-api",
  "version": "1.0.0",
  "description": "",
  "main": "jest.config.js",
  "scripts": {
    "test": "jest",
    "tsc": "tsc"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/aws-lambda": "^8.10.50",
    "@types/jest": "^25.2.1",
    "@types/node": "^13.11.1",
    "jest": "^25.3.0",
    "ts-jest": "^25.3.1",
    "typescript": "^3.8.3"
  },
  "dependencies": {
    "aws-sdk": "^2.760.0"
  }
}

  1. 以下のファイルをtemplate-parameter-it.jsonとしてルートディレクトリに作成する。
template-parameter-it.json
{
  "Parameters": {
    "Env": "it",
    "Prefix": "demo-digi-{グループ番号}-",
    "ApiStage": "apiIT",
    "TableName": "demo-digi-{グループ番号}-it",
    "LambdaRole": "arn:aws:iam::317076571640:role/LambdaAccessRole",
    "CloudWatchRole": "arn:aws:iam::317076571640:role/APIGatewayPushToCloudWatchLogsRole"
  }
}

  1. 8で作成したtemplate-parameter-it.jsonを修正する
  • {グループ番号}となっている部分を各グループの番号に修正(計2か所)
  1. 以下のコマンドを実行して、リモートリポジトリに資源をアップロードする。

    1. カレントディレクトリをローカルリポジトリに移動する。

      cd c:/work/training-api-{グループ番号}-
      
    2. nodemodulesを作成する。

      npm ci
      
    3. すべてのファイルをステージングする。

      git add .
      
    4. コミットメッセージを付与してファイルをコミットする。

      git commit -m "init"
      
    5. ローカルリポジトリから CodeCommit のリモートリポジトリにファイルをプッシュする。

      git push
      
  2. CodeCommit コンソールを開き、該当リポジトリを選択。資源が反映されていることを確認する。

Cloudformationでパイプラインを作成

  1. codecommitでit ブランチを作成してリモートにプッシュ

    git checkout -b it
    git push --set-upstream origin it
    
  2. it 用のパイプラインを作成(テンプレート)

  • テンプレートの作成 ローカルに api-pipeline-template-{グループ番号}.yaml のファイルを作成
api-pipeline-template-{グループ番号}.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: demo-digi-api template

Parameters:
  DeployBucket:
    Type: String
  Env:
    Type: String
    AllowedValues:
      - 'it'
      - 'st'
      - 'uat'
      - 'stg'

Resources:
  #------------------------------------------------------
  # 開発環境 SAMテンプレートをパッケージするCodeBuildプロジェクト
  #------------------------------------------------------
  DevDeployCodeBuildProject:
    # CodeBuildの設定
    # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-codebuild-project.html
    Type: AWS::CodeBuild::Project
    # [要修正]各グループの番号を入力
    # codebuildのプロジェクトネームを指定
    Properties:
      Name: !Sub 'demo-digi-api-{グループ番号}-build-${Env}'
      Description: Build project for packaging SAM template
      # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-artifacts.html
      Artifacts:
        Type: CODEPIPELINE
      # CodeBuildの環境設定
      # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-environment.html
      Environment:
        Type: LINUX_CONTAINER
        ComputeType: BUILD_GENERAL1_MEDIUM
        Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
        # 環境変数の設定
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-environmentvariable.html
        EnvironmentVariables:
          - Name: Env
            Value: !Ref Env
      # CodeBuildで利用するIamRoleの設定
      ServiceRole: 'arn:aws:iam::317076571640:role/CodePipelineRole'
      # BuildSpecの設定
      # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-source.html
      Source:
        BuildSpec: 'buildspec.yml'
        Type: CODEPIPELINE

  #------------------------------------------------------
  # 開発環境 CodeCommitリポジトリからアプリをデプロイするCodePipeline
  #------------------------------------------------------
  DevDeployPipeline:
    # CodePipelineの設定
    # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-pipeline.html
    Type: AWS::CodePipeline::Pipeline
    Properties:
      # アーティファクト保存場所(アーティファクトとはソースコード・定義ファイルとかの集合体)
      ArtifactStore:
        Location: !Ref DeployBucket
        Type: S3
      # [要修正]各グループの番号を入力
      # パイプラインの名称を設定
      Name: !Sub 'demo-digi-api-{グループ番号}-pipeline-${Env}'
      RoleArn: 'arn:aws:iam::317076571640:role/CodePipelineRole'
      # Stageの設定 今回CodePipelineで利用するStageはSource(CodeCommit)とBuild(CodeBuild)とDeploy(CodeDeploy)2つ
      # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-codepipeline-pipeline-stages.html#cfn-codepipeline-pipeline-stages-actions
      Stages:
        - Name: Source
          # Actionsでこのステージは何をするステージか設定する
          # ActionTypeId: ソース元の設定(CodeCommit以外にGitHubやBitBucketがある)
          # Configuration: 詳細の設定 下述 ConfigurationはActionTypeIDによって内容が異なる
          # OutputArtifacts: このステージが出力するアーティファクト名の設定
          # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-codepipeline-pipeline-stages-actions.html
          Actions:
            - Name: Source
              ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: CodeCommit
                Version: 1
              # 変更検出された場合に動くトリガー 今回はdemo-digi-apiのEnvブランチが変更されたらパイプラインが起動する
              # https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-pipeline-structure.html#action-requirements
              Configuration:
                # [要修正]各グループの番号を入力
                # 作成したリポジトリを設定
                RepositoryName: !Sub 'training-api-{グループ番号}'
                BranchName: !Ref Env
              OutputArtifacts:
                - Name: SourceZip
        - Name: Build
          Actions:
            - Name: Build
              # Actionsでこのステージは何をするステージか設定する
              # ActionTypeId: ビルドするステージを選択(CodeBuild以外にJenkinsがある)
              # Configuration: 詳細の設定 DevDeployCodeBuildProject ConfigurationはActionTypeIDによって内容が異なる
              # InputArtifacts: このステージが入力するアーティファクト名の設定
              # OutputArtifacts: このステージが出力するアーティファクト名の設定
              # https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-pipeline-structure.html#action-requirements
              ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: 1
              Configuration:
                ProjectName: !Ref DevDeployCodeBuildProject
              InputArtifacts:
                - Name: SourceZip
              OutputArtifacts:
                - Name: BuiltZip
        - Name: Deploy
          Actions:
            - Name: CreateChangeSet
              # Actionsでこのステージは何をするステージか設定する
              # ActionTypeId: Deployステージ(1/2)
              # Configuration: 下述
              # InputArtifacts: このステージが入力するアーティファクト名の設定
              # https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-pipeline-structure.html#action-requirements
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CloudFormation
                Version: 1
              Configuration:
                # CHANGE_SET_REPLACE ChangeSetの作成
                # ChangeSetとは? cloudformationのスタックの一歩手前の状態
                # ChangeSetでスタックがどう置き換わるか?何が削除されて、何が作成されるか確認できる
                # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-action-reference.html
                ActionMode: CHANGE_SET_REPLACE
                # [要修正]各グループの番号を入力
                # changeSetの名称を設定
                ChangeSetName: !Sub 'demo-digi-api-{グループ番号}-change-set-${Env}'
                # [要修正]各グループの番号を入力
                # 作成するスタックの名称を設定
                StackName: !Sub 'demo-digi-api-aws-services-{グループ番号}-stack-${Env}'
                Capabilities: CAPABILITY_IAM
                TemplatePath: BuiltZip::demo-digi-api-template-output.yaml
                TemplateConfiguration: !Sub 'BuiltZip::template-parameter-${Env}.json'
                RoleArn: 'arn:aws:iam::317076571640:role/CodePipelineRole'
              InputArtifacts:
                - Name: BuiltZip
              RunOrder: 1
            - Name: ExecuteChangeSet
              # Actionsでこのステージは何をするステージか設定する
              # ActionTypeId: Deployステージ(2/2)
              # Configuration: 下述
              # https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-pipeline-structure.html#action-requirements
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: 1
                Provider: CloudFormation
              # CHANGE_SET_EXECUTE Changeの実行
              # ChangeSetを実際にスタックに置き換えてAWS資源(例えばこのパイプラインだとlambda)を作成する
              # 作成されるスタックの名前もここで設定する
              # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-action-reference.html
              Configuration:
                ActionMode: CHANGE_SET_EXECUTE
                # [要修正]各グループの番号を入力
                # changeSetの名称を設定
                ChangeSetName: !Sub 'demo-digi-api-{グループ番号}-change-set-${Env}'
                # [要修正]各グループの番号を入力
                # 作成するスタックの名称を設定
                StackName: !Sub 'demo-digi-api-aws-services-{グループ番号}-stack-${Env}'
              RunOrder: 2

  • DeployBucket: aws-training-digidept-work-dev
  • ENV: it
    を指定します。
  1. api-pipeline-template-{グループ番号}.yaml のファイルを修正
  • 「ctr+F」で「要修正」と検索
  • {グループ番号}となっている部分をそれぞれのグループ番号に修正(計7か所)
  1. api-pipeline-template-{グループ番号}.yaml のファイルをアップロード
    1. AWS コンソールでcloudformationを開く
    2. スタック作成を押下する

      「テンプレート準備完了を選択」 -> 「テンプレートファイルのアップロード」で「api-pipeline-template-{グループ番号}.yaml」を選択 -> 「次へ」を押下
    3. スタック名で「demo-digi-api-{グループ番号}-stack-it」を入力-> DeployBucketに「aws-training-digidept-work-dev」を入力->Envで「it」を選択 -> 「次へ」を押下
    4. アクセス許可 IAM ロール名で「CodePipeline」を選択 -> 「次へ」を押下
    5. 何も変更せず「送信」を押下
  2. CloudFormationのスタックを開き「demo-digi-api-{グループ番号}-stack-it」ができているか確認
  3. CodePipelineを開き「demo-digi-api-{グループ番号}-pipeline-it」ができているか確認
  • エラーが出ずにdeployできていればOK