dorivenの日記

気がついたら社会人。気になる技術的なことについて少しずつ書いていけたらと思っております。

golang + SAM でLambdaのCI/CD(GithubActions)でのデプロイのことはじめ

samをCI上でデプロイする方法を紹介する。

対象読者

  • Github上でCIの設定などを行ったことがある人
  • AWSを普段から触れているがLambdaのSAMを触ったことがない・難しく感じている人
  • Lambda+SAMを触れたことがあるがデプロイをCI環境からやったことがない人

前提

環境

以下の環境で実行を行っている。

レポジトリに今回の一連の作業のコードが上げている。 https://github.com/d0riven/LearningSAMDeploy

すべてのコマンドは このレポジトリのルートパス上で実行している ものとする。

知識

  • IAMやAWSのクレデンシャルや設定周りの知識は知っている
    • AWS_PROFILE, AWS_ACCESS_KEY_ID, ~/.aws/credential などの文字を見てどのようなものか分かるくらいの知識

スクランナーとしてMakefileを採用しているが、そこの知識がなくても理解できるように話をすすめる。

あるとより理解が進むもの

  • dockerについての知識
    • 実行環境にdockerを採用しない場合はDocker周りの説明を無視して構わない

SAMとは

Serverless Application Model の略。 AWS Cloudformation の拡張記述で、Lambdaと関連リソースの作成が容易に行えるライブラリ。 Python製のCLIツールなので導入にあたってpythonの環境を構築する必要がある。

事前準備

SAMを利用するにあたって、SAMの導入やSAMをCI上で実行するときのIAMユーザの用意を行う必要がある。

SAMの導入

導入方法はいくつかある。 * ローカルマシン(今回であればMac)にインストールする * コンテナなどの仮想環境を利用する

Macならhomebrewを使うというのも一手だが、それだとCIなどの異なる環境で実行しにくくなるためここではDockerでSAMの実行環境のコンテナイメージを作成する方法を採用する。 Dockerを使うことでどの環境でも同様の実行環境でデプロイが可能になるので、環境差異を極限まで小さくできるメリットがある。 ただしsam local invokeを行おうとすると、docker in docker 状態が発生してしまうので、そこを回避する方法を検討する必要があったりはするのでコンテナを採用しないという道もある。

SAMのdockerイメージの用意

SAMの実行環境にコンテナを採用しない場合はここは読み飛ばして良い

SAMのコンテナイメージは用意されていないので、golang+SAMの実行環境を詰め込んだイメージをdocker hubに配置した。 CIで実行するときにイメージを指定するときに認証情報などを渡さなくて良いのでパブリックなDockerHubレポジトリにイメージを配置しているが、ここはプロジェクトによってプライベートにしたり異なるプラットフォーム(AWS ECR, Google GCRなど)のレポジトリを使用しても良い。 https://github.com/d0riven/LearningSAMDeploy/tree/master/build/sam を参照。

Dockerfileは下記

FROM golang:1.16

RUN apt update && apt install -y python3-pip
RUN pip3 install aws-sam-cli==1.23.0

上記のDockerfileの準備が出来たら以下に対応するコマンドを叩いてDockerHubにアップロードしていく。

⟩ make -C build/sam release -n
docker build -t doriven/sam-cli-go:1.23.0 ./
docker login
docker push doriven/sam-cli-go:1.23.0

docker hubのリポジトリにイメージがアップロードがされる。 https://hub.docker.com/repository/docker/doriven/sam-cli-go

これでgolang+SAM実行環境のdockerイメージの準備は出来た。

MakefileでSAMの実行コマンドを以下のように定義している。 ローカル環境のクレデンシャルをコンテナイメージにマウントする形で利用するようにし、 レポジトリのルートディレクトリを/workにマウントしてワーキングディレクトリとすることでローカルでSAMコマンドを実行するのと同様の感覚で利用できるようにしている。

https://github.com/d0riven/LearningSAMDeploy/blob/master/Makefile

SAM := docker run --rm \
  -v ~/.aws:/root/.aws \
  -v $(CURDIR):/work \
  -w /work \
  doriven/sam-cli-go:1.23.0 sam

Lambdaの実行ファイルを配置するためのS3バケットの用意

マネジメントコンソールから手動で作成してもらって構わない。 今回のハンズオンでは doriven-lambda-artifacts というバケットを用意している。 もちろん公開はしていないので、自身でハンズオンをしたい場合は異なるバケットを作成する必要がある。

CIでSAMを動かすIAMユーザの準備

SAMはAWSリソースをいじるのでIAMユーザを作成して、権限を付与し、CI上で利用するアクセスキーを生成する必要がある。

今回はterraformを利用してユーザの作成を行ったが、terraformについての詳細は省く。 気になる人はリポジトリの以下のURLを参照してもらえればどのようなことがやっているのか理解できるはず。

https://github.com/d0riven/LearningSAMDeploy/tree/master/deployoments/stacks

IAMユーザに必要な権限

重要なのは どのような権限を付与する必要があるのか、という部分だ。 それぞれの権限をなぜ付与しているのかという部分を、statement毎に#でコメントを付与しているので参照してほしい。 (当たり前だがJSONに#が入っていると動かないのでコピーするときはコメントを除いてほしい)

{
    "Version": "2012-10-17",
    "Statement": [
        # "sam deploy"コマンドを叩くときに実行環境上で必要になる権限
        # 実際のリソース操作はCloudFormationが行うのでここではlambda作成などの強い権限は付与しない
        {
            "Sid": "SamDeploy",
            "Effect": "Allow",
            "Action": [
                "cloudformation:Update*",
                "cloudformation:Get*",
                "cloudformation:ExecuteChangeSet",
                "cloudformation:Describe*",
                "cloudformation:Create*"
            ],
            "Resource": "*"
        },
        # "sam validate"コマンドを叩くときに実行環境上で必要になる権限
        # validationを行うときにiamポリシーの一覧などをチェックしているのか、iam:ListPoliciesの権限を要求される
        {
            "Sid": "SAMValidate",
            "Effect": "Allow",
            "Action": "iam:ListPolicies",
            "Resource": "*"
        },
        # "sam package"コマンドを叩くときに実行環境上で必要になる権限
        # packagelambdaが参照するgoのバイナリコードをS3にアップロードするのでs3:PutObject権限が必要になる
        {
            "Sid": "SAMPackage",
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::doriven-lambda-artifacts/learning-sam-ci-deploy/sample/*"
        },
        # "sam deploy"コマンドを叩くときにCloudFormation上で必要になる権限
        {
            "Sid": "AllowChangeByCF",
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "logs:*",
                "lambda:*",
                "iam:List*",
                "iam:*Role*",
                "cloudwatch:*"
            ],
            "Resource": "*",
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "aws:CalledVia": [
                        "cloudformation.amazonaws.com"
                    ]
                }
            }
        }
    ]
}

本番運用する上で検討するべきところは以下のstatement。 CloudFormation自体がリソースを管理するサービスなのでかなり強い権限を与える必要がある。 必要最低限の権限を与えるとSAMのリソース作成するためにいちいち権限を変更する必要が出てくるなど、取り回しが悪くなる一方で強い権限を与えすぎる万が一のアクセスキーの流出時の影響が大きくなるので正直いって悩ましい。 ここらへんはもっと調整して条件付けで取り回しとセキュリティの両方を担保できる方法を検討していく必要がある。 ただしCalledViaでCFnを指定しているので、キーが流出したからといっても簡単に利用される訳ではなく、CloudFormationを経由して実行して初めてこれらの権限を行使できるようになる。 よく聞く話が暗号通貨をマイニングするために奪取したアクセスキーを使って高価なEC2インスタンスを立てるというのを聞くがCalledViaを付けているのでいきなりEC2インスタンスが作れないという訳だ(今回はそもそもEC2の権限も与えてないので作れないのだが)

{
    "Sid": "AllowChangeByCF",
    "Effect": "Allow",
    "Action": [
        "s3:Get*",
        "logs:*",
        "lambda:*",
        "iam:List*",
        "iam:*Role*",
        "cloudwatch:*"
    ],
    "Resource": "*",
    "Condition": {
        "ForAnyValue:StringEquals": {
            "aws:CalledVia": [
                "cloudformation.amazonaws.com"
            ]
        }
    }
}

How to SAM

dockerイメージやIAMの準備が出来たのでようやくSAMを実際に触る工程を実施していく。 SAMは実際に以下の手順で構築していく。

  1. SAMテンプレートファイルの作成
  2. ソースコードのパッケージング & CloudFormationテンプレートファイルへの変換
  3. デプロイ(2で変換したCloudFormationテンプレートファイルを適用)

SAMテンプレートファイルの作成

SAMには各言語に対応したテンプレートファイルの雛形を用意してくれるinitというサブコマンドが用意されている。 以下のように対話形式で作れるのでまずはこれをひな形にするなどしてもよい。

root@38fb663f0a51:/go# sam init
Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1
What package type would you like to use?
        1 - Zip (artifact is a zip uploaded to S3)
        2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 1

Which runtime would you like to use?
        1 - nodejs14.x
        2 - python3.8
        3 - ruby2.7
        4 - go1.x
        5 - java11
        6 - dotnetcore3.1
        7 - nodejs12.x
        8 - nodejs10.x
        9 - python3.7
        10 - python3.6
        11 - python2.7
        12 - ruby2.5
        13 - java8.al2
        14 - java8
        15 - dotnetcore2.1
Runtime: 4

Project name [sam-app]:

Cloning app templates from https://github.com/aws/aws-sam-cli-app-templates

AWS quick start application templates:
        1 - Hello World Example
        2 - Step Functions Sample App (Stock Trader)
Template selection: 1

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Runtime: go1.x
    Dependency Manager: mod
    Application Template: hello-world
    Output Directory: .

    Next steps can be found in the README file at ./sam-app/README.md

root@38fb663f0a51:/go# cat sam-app/template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 5

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello-world/
      Handler: hello-world
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Events:
        CatchAll:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: GET
      Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
        Variables:
          PARAM1: VALUE

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldAPI:
    Description: "API Gateway endpoint URL for Prod environment for First Function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "First Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

上記の雛形だけでは必要なリソースの追加など、ドキュメントを参考にしたいことが多分に出てくる。 そのときは以下のドキュメントを参考にすることで、必要なリソースをどのように追加すれば良いかが分かる。 https://github.com/awsdocs/aws-sam-developer-guide/blob/master/doc_source/index.md

今回はCIでのデプロイをすることが目的なのでcronのように1分間隔で実行するLambdaを用意する。 結果、上記のテンプレートを参考にしつつ以下のようになった。

気になる項目は様々あると思うが重要な部分にはコメントを追加してある。

AWSTemplateFormatVersion: '2010-09-09'
Transform:                AWS::Serverless-2016-10-31
Description:              >
                          sam-app
                          Sample SAM Template for sam-app

Globals:
  Function:
    Timeout: 5

# !Ref パラメータ名 とやることでデプロイ時にパラメータを指定することができる
# 環境変数の定義などに使う、などがぱっと思いつく使い方かな
Parameters:
  Hoge:
    Type:    String
    Default: Default

Resources:
  SampleFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: learning-sam-ci-deploy_sample # Lambda関数の名前。これを設定しないとかなり冗長な名前をつけられるので設定することを推奨する
      CodeUri:      dist/  # package時にZipで固めてS3にアップロードする対象のディレクトリ。SAMテンプレートファイルがあるところをワーキングディレクトリとして見るのでその点に注意
      Handler:      sample # CodeUriで指定したディレクトリ内でLambda実行時に実行するファイルを指定する。goならbuildしたバイナリファイルを指定してやればよい
      Runtime:      go1.x
      Events: # Lambdaのトリガーとなるイベントを指定する。どのようなイベントがあるかはドキュメント参照のこと
        CWEvent:
          Type: Schedule
          Properties:
            Schedule:    'rate(1 minute)'
            Name:        SampleSchedule
            Description: sample schedule
            Enabled:     False
      Environment:
        Variables:
          HOGE: !Ref Hoge

ソースコードのパッケージング & CloudFormationテンプレートファイルへの変換

テンプレートファイル(template.yaml)を用意したので今度はパッケージング周りに触れていく。 今回のリポジトリディレクトリ構成は以下のようになっている。

/
└─ cmd/sample/
   ├─ main.go
   ├─ template.yaml
   ├─ dist/ (packageコマンド実行前に生成されている必要がある)
   │   └─ sample
   └─ output.yaml (packageコマンド実行時に生成)

Makefileでは以下の流れでコマンドが実行されるようになっている。

  1. go buildでdist/sample にバイナリファイルを生成
  2. lambdaの実行環境に合わせてGOOS=linux GOARCH=amd64環境変数を必ず指定(これをやらないと実行時にエラーで落ちる)
  3. validateコマンドでtemplate.yamlを検証
  4. packageコマンドでZipに固めてS3バケットにファイルをアップロード & CloudFormationテンプレートファイルへ変換した output.yaml を生成
  5. s3-bucketとs3-prefixオプションを使って、 s3://doriven-lambda-artifacts/learning-sam-ci-deploy/sample/* にzipファイルがアップロードされるようにしている
  6. ここらへんバケットやパスの運用はチームによる
⟩ make deploy -n
go test ./...
rm -rf cmd/sample/dist/
GOOS=linux GOARCH=amd64 go build -o cmd/sample/dist/sample cmd/sample/main.go
docker run --rm -v ~/.aws:/root/.aws -v /Users/doriven/code/LearningSamCIDeploy:/work -w /work doriven/sam-cli-go:1.23.0 sam validate -t cmd/sample/template.yaml
docker run --rm -v ~/.aws:/root/.aws -v /Users/doriven/code/LearningSamCIDeploy:/work -w /work doriven/sam-cli-go:1.23.0 sam package \
                -t cmd/sample/template.yaml \
                --debug \
                --s3-bucket doriven-lambda-artifacts \
                --s3-prefix learning-sam-ci-deploy/sample \
                --output-template-file cmd/sample/output.yaml
# ここから下はdeployコマンドなので後述で説明
...

デプロイ

パッケージングが済んだので次に変換したCloudFormationテンプレートファイルを適用してデプロイをしていく。 コマンド的には以下のように実行されている。 オプションの付与をなぜ行っているかはコメントとして記述しておいた。

⟩ make deploy -n
...
docker run --rm -v ~/.aws:/root/.aws -v /Users/doriven/code/LearningSamCIDeploy:/work -w /work doriven/sam-cli-go:1.23.0 sam deploy \
                -t cmd/sample/template.yaml \
                --debug \
                --s3-bucket doriven-lambda-artifacts \
                --s3-prefix learning-sam-ci-deploy/sample \
                --no-fail-on-empty-changeset \ # CloudFormationに変更がなくてもdeployコマンドがエラーにならないようにする。これはREADMEのみの変更などLambdaの挙動に影響しない場合の変更時にエラーで落ちないようにするためのもの
                --capabilities CAPABILITY_IAM \ # IAMリソースを作成する場合に付与する必要がある。SAMはLambdaを実行するIAMロールを自動的に作成するため、この権限を付与する必要がある
                --capabilities CAPABILITY_NAMED_IAM \ # 同上(IAMロールに名前を指定している場合に必要になる。脳死でつけて良い)
                --stack-name learning-sam-ci-deploy-sample \ # CFnのstack-nameを指定している。
                --parameter-overrides \
                        HOGE=FUGAFUGA

上記のコマンドを実行するとCFnのスタックが作成され、Lambda・IAMロール・CloudwatchLogs・トリガーとなるイベント(今回はCloudWatchEvent)のリソースがAWS上に作成される形になる。

Run SAM with CI

SAMの使い方、今回のサンプルで作成されるリソース周りを理解したということで今度はCIからSAMを実行する術を紹介していく。 今回のサンプル用のCIはGithub Actionsを採用する。他のCIでのやり方は各自で調査してほしい。 主にやることは以下だ。

  • CIのワークフロー設定
  • アクセスキーの生成・CI上でアクセスキーの機密情報を設定

CIのワークフロー設定

Github Actionsの設定方法の説明をするとそれだけで1記事書けてしまうのでここでは割愛する。 もしも知らない人は以下の公式ドキュメントを読んでみたり、ネットで使い方を紹介している記事があるはずなのでそれを参照すると良い。 ちなみにGithubActionsは変化が著しいので公式ドキュメントを読むことを筆者は推奨する。 https://docs.github.com/en/actions/quickstart

今回のレポジトリでは以下のようなワークフローを設定した。 yamlにコメントを追記してある。

name: deploy

on:
  pull_request:
  push:
    branches:
      - master

jobs:
  test: # test用のジョブ
    runs-on: ubuntu-latest
    container:
      image: doriven/sam-cli-go:1.23.0 # docker-hub にアップロードしたイメージをここで使っている
    steps:
      -
        uses: actions/checkout@v2
      -
        uses: actions/cache@v2
        with:
          path: |
                vendor/
          key: go-${{ hashFiles('go.sum') }}
          restore-keys: |
            go-
      -
        run: make deps # vendor/ ディレクトリにgoで使用するライブラリ郡を配置
      -
        run: make test # test を実行する
  deploy:
    needs: test # deployを実行する前にtestが通っていることを担保しておく
    if: github.ref == 'refs/heads/master' # マージされたときだけデプロイコマンドが動き出すように設定。最初にデプロイの動作確認をするときはこの行を外しておくと良い
    runs-on: ubuntu-latest
    container:
      image: doriven/sam-cli-go:1.23.0
    steps:
      -
        uses: actions/checkout@v2
      -
        uses: actions/cache@v2
        with:
          path: |
            vendor/
          key: go-${{ hashFiles('go.sum') }}
          restore-keys: |
            go-
      -
        run: make deps
      -
        uses: aws-actions/configure-aws-credentials@v1 # 後述するsecretsに設定したアクセスキーを環境変数に読み込む
        with:
          aws-access-key-id:     ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1
      -
        run: make deploy SAM=sam # package -> deployまでの一連のジョブを実行。CI上ではdockerコンテナ上でコマンドが叩かれるのでsamのコマンドはdockerを使わずにコンテナ内のsamコマンドを使うようにしている

アクセスキーの生成・CI上でアクセスキーの機密情報を設定

アクセスキーの生成

CIのワークフローを設定しても今のままだとAWSの権限が足りずにSAMコマンドを叩くことができない。 そのためCI上にSAMをデプロイできる権限を持ったユーザのアクセスキーを設定する必要がある。 サンプルではユーザはすでにterraformで作成済みなので、マネジメントコンソールからアクセスキーを発行しておく。 画像つきで発行手順を紹介してくれているページがあったので、以下のURLを参考に進めてみると良い。 https://www.umayadia.com/AWS/AWS002GetAccessKeyID.htm

GithubActions上にアクセスキーを設定

さて、アクセスキーを生成・取得したところで次にリポジトリのSecretsとしてアクセスキーを設定していく。 リポジトリのシークレットの追加に関しては公式サイトのURLを載せておいた。 https://docs.github.com/ja/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository

今回は AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY という名前でアクセスキーを設定する。 AWS_ACCESS_KEY_ID にアクセスキーIDを、 AWS_SECRET_ACCESS_KEY にシークレットアクセスキーを設定すれば良い。

実演

お疲れ様。 ここまで定義できたらようやくGithubActions上でSAMのデプロイができるようになった。 以下が実際にactionsの実行状況が分かるページだ。 とはいえログの詳細が見れないと思うので、以下にログについて記載をした。

https://github.com/d0riven/LearningSAMDeploy/actions/runs/813529535

sam package \
    -t cmd/sample/template.yaml \
    --debug \
    --s3-bucket doriven-lambda-artifacts \
    --s3-prefix learning-sam-ci-deploy/sample \
    --output-template-file cmd/sample/output.yaml
2021-05-05 13:21:50,954 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2021-05-05 13:21:50,956 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2021-05-05 13:21:50,956 | Sending Telemetry: {'metrics': [{'templateWarning': {'requestId': '6125ca3f-d108-47b0-9dbb-36d080578f55', 'installationId': '990420ea-065b-4c14-98f9-c67dbff181ec', 'sessionId': '2bc355fa-358c-4414-855a-9fa429294c43', 'executionEnvironment': 'GitHubAction', 'ci': True, 'pyversion': '3.7.3', 'samcliVersion': '1.23.0', 'awsProfileProvided': False, 'debugFlagProvided': True, 'region': '', 'warningName': 'CodeDeployWarning', 'warningCount': 0}}]}
2021-05-05 13:21:51,312 | HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com', port=443): Read timed out. (read timeout=0.1)
2021-05-05 13:21:51,313 | Sending Telemetry: {'metrics': [{'templateWarning': {'requestId': '513a5cea-e634-4e6f-8ead-d0dd1f7f8050', 'installationId': '990420ea-065b-4c14-98f9-c67dbff181ec', 'sessionId': '2bc355fa-358c-4414-855a-9fa429294c43', 'executionEnvironment': 'GitHubAction', 'ci': True, 'pyversion': '3.7.3', 'samcliVersion': '1.23.0', 'awsProfileProvided': False, 'debugFlagProvided': True, 'region': '', 'warningName': 'CodeDeployConditionWarning', 'warningCount': 0}}]}
2021-05-05 13:21:51,668 | HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com', port=443): Read timed out. (read timeout=0.1)
2021-05-05 13:21:51,668 | Using config file: samconfig.toml, config environment: default
2021-05-05 13:21:51,668 | Expand command line arguments to:
2021-05-05 13:21:51,668 | --template_file=/__w/LearningSAMDeploy/LearningSAMDeploy/cmd/sample/template.yaml --s3_bucket=doriven-lambda-artifacts --s3_prefix=learning-sam-ci-deploy/sample --output_template_file=cmd/sample/output.yaml 

Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  262144 / 4324955  (6.06%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  524288 / 4324955  (12.12%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  786432 / 4324955  (18.18%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  1048576 / 4324955  (24.24%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  1310720 / 4324955  (30.31%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  1572864 / 4324955  (36.37%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  1835008 / 4324955  (42.43%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  2097152 / 4324955  (48.49%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  2359296 / 4324955  (54.55%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  2621440 / 4324955  (60.61%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  2883584 / 4324955  (66.67%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  3145728 / 4324955  (72.73%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  3407872 / 4324955  (78.80%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  3670016 / 4324955  (84.86%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  3932160 / 4324955  (90.92%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  4194304 / 4324955  (96.98%)

Successfully packaged artifacts and wrote output template to file cmd/sample/output.yaml.
Execute the following command to deploy the packaged template
sam deploy --template-file /__w/LearningSAMDeploy/LearningSAMDeploy/cmd/sample/output.yaml --stack-name <YOUR STACK NAME>

Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  4324955 / 4324955  (100.00%)
2021-05-05 13:21:55,089 | Sending Telemetry: {'metrics': [{'commandRun': {'requestId': 'd083a1b5-4bfb-48ab-b063-d27ca19ab9b7', 'installationId': '990420ea-065b-4c14-98f9-c67dbff181ec', 'sessionId': '2bc355fa-358c-4414-855a-9fa429294c43', 'executionEnvironment': 'GitHubAction', 'ci': True, 'pyversion': '3.7.3', 'samcliVersion': '1.23.0', 'awsProfileProvided': False, 'debugFlagProvided': True, 'region': '', 'commandName': 'sam package', 'duration': 4133, 'exitReason': 'success', 'exitCode': 0}}]}
2021-05-05 13:21:55,430 | HTTPSConnectionPool(host='aws-serverless-tools-telemetry.us-west-2.amazonaws.com', port=443): Read timed out. (read timeout=0.1)
sam deploy \
    -t cmd/sample/template.yaml \
    --debug \
    --s3-bucket doriven-lambda-artifacts \
    --s3-prefix learning-sam-ci-deploy/sample \
    --no-fail-on-empty-changeset \
    --capabilities CAPABILITY_IAM \
    --capabilities CAPABILITY_NAMED_IAM \
    --stack-name learning-sam-ci-deploy-sample \
    --parameter-overrides \
        HOGE=FUGAFUGA
2021-05-05 13:21:55,745 | Telemetry endpoint configured to be https://aws-serverless-tools-telemetry.us-west-2.amazonaws.com/metrics
2021-05-05 13:21:55,746 | Using config file: samconfig.toml, config environment: default
2021-05-05 13:21:55,746 | Expand command line arguments to:
2021-05-05 13:21:55,746 | --template_file=/__w/LearningSAMDeploy/LearningSAMDeploy/cmd/sample/template.yaml --s3_bucket=doriven-lambda-artifacts --s3_prefix=learning-sam-ci-deploy/sample --capabilities=('CAPABILITY_NAMED_IAM',) --stack_name=learning-sam-ci-deploy-sample --parameter_overrides={'HOGE': 'FUGAFUGA'} 

Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  262144 / 4324955  (6.06%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  524288 / 4324955  (12.12%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  786432 / 4324955  (18.18%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  1048576 / 4324955  (24.24%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  1310720 / 4324955  (30.31%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  1572864 / 4324955  (36.37%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  1835008 / 4324955  (42.43%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  2097152 / 4324955  (48.49%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  2359296 / 4324955  (54.55%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  2621440 / 4324955  (60.61%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  2883584 / 4324955  (66.67%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  3145728 / 4324955  (72.73%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  3407872 / 4324955  (78.80%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  3670016 / 4324955  (84.86%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  3932160 / 4324955  (90.92%)
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  4194304 / 4324955  (96.98%)

    Deploying with following values
    ===============================
    Stack name                   : learning-sam-ci-deploy-sample
    Region                       : ap-northeast-1
    Confirm changeset            : False
    Deployment s3 bucket         : doriven-lambda-artifacts
    Capabilities                 : ["CAPABILITY_NAMED_IAM"]
    Parameter overrides          : {"HOGE": "FUGAFUGA"}
    Signing Profiles             : {}

Initiating deployment
=====================
Uploading to learning-sam-ci-deploy/sample/8d6221ae065487b2d47c1ba8e941c9d0  4324955 / 4324955  (100.00%)
2021-05-05 13:21:59,333 | Collected default values for parameters: {'Hoge': 'Default'}
2021-05-05 13:21:59,355 | 1 stacks found in the template
2021-05-05 13:21:59,355 | Collected default values for parameters: {'Hoge': 'Default'}
2021-05-05 13:21:59,375 | 1 resources found in the stack 
2021-05-05 13:21:59,375 | Collected default values for parameters: {'Hoge': 'Default'}
2021-05-05 13:22:00,159 | Stack with id learning-sam-ci-deploy-sample does not exist


Waiting for changeset to be created..

CloudFormation stack changeset
-------------------------------------------------------------------------------------------------
Operation                LogicalResourceId        ResourceType             Replacement            
-------------------------------------------------------------------------------------------------
+ Add                    SampleFunctionCWEventP   AWS::Lambda::Permissio   N/A                    
                         ermission                n                                               
+ Add                    SampleFunctionCWEvent    AWS::Events::Rule        N/A                    
+ Add                    SampleFunctionRole       AWS::IAM::Role           N/A                    
+ Add                    SampleFunction           AWS::Lambda::Function    N/A                    
-------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:***:changeSet/samcli-deploy1620220920/10607331-89a3-4087-99c0-ad2a51b08049


2021-05-05 13:22:13 - Waiting for stack create/update to complete

CloudFormation events from changeset
-------------------------------------------------------------------------------------------------
ResourceStatus           ResourceType             LogicalResourceId        ResourceStatusReason   
-------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS       AWS::IAM::Role           SampleFunctionRole       -                      
CREATE_IN_PROGRESS       AWS::IAM::Role           SampleFunctionRole       Resource creation      
                                                                           Initiated              
CREATE_COMPLETE          AWS::IAM::Role           SampleFunctionRole       -                      
CREATE_IN_PROGRESS       AWS::Lambda::Function    SampleFunction           -                      
CREATE_IN_PROGRESS       AWS::Lambda::Function    SampleFunction           Resource creation      
                                                                           Initiated              
CREATE_COMPLETE          AWS::Lambda::Function    SampleFunction           -                      
CREATE_IN_PROGRESS       AWS::Events::Rule        SampleFunctionCWEvent    Resource creation      
                                                                           Initiated              
CREATE_IN_PROGRESS       AWS::Events::Rule        SampleFunctionCWEvent    -                      
CREATE_COMPLETE          AWS::Events::Rule        SampleFunctionCWEvent    -                      
CREATE_IN_PROGRESS       AWS::Lambda::Permissio   SampleFunctionCWEventP   Resource creation      
                         n                        ermission                Initiated              
CREATE_IN_PROGRESS       AWS::Lambda::Permissio   SampleFunctionCWEventP   -                      
                         n                        ermission                                       
CREATE_COMPLETE          AWS::Lambda::Permissio   SampleFunctionCWEventP   -                      
                         n                        ermission                                       
CREATE_COMPLETE          AWS::CloudFormation::S   learning-sam-ci-         -                      
                         tack                     deploy-sample                                   
-------------------------------------------------------------------------------------------------

Successfully created/updated stack - learning-sam-ci-deploy-sample in ap-northeast-1

Uploading to learning-sam-ci-deploy/sample/28fc3f689e02ba55bb1a6df11c9afa28.template  804 / 804  (100.00%)
2021-05-05 13:24:02,666 | Sending Telemetry: {'metrics': [{'commandRun': {'requestId': 'cf47c925-bfc5-4584-810d-ccfc25daa59c', 'installationId': '990420ea-065b-4c14-98f9-c67dbff181ec', 'sessionId': '02e1550c-f275-472c-9cf0-a139d27d5994', 'executionEnvironment': 'GitHubAction', 'ci': True, 'pyversion': '3.7.3', 'samcliVersion': '1.23.0', 'awsProfileProvided': False, 'debugFlagProvided': True, 'region': '', 'commandName': 'sam deploy', 'duration': 126918, 'exitReason': 'success', 'exitCode': 0}}]}
2021-05-05 13:24:03,038 | Telemetry response: 200