LambdaをCodePipelineでデプロイする

## はじめに
テリーの発売を記念して、記事を１つ公開します。
今回は、CodePipeline（CodeBuild/CodeDeploy）を使ってLambdaのデプロイを試みました。業務で使うのでその学習のためです。CodePipelineを使ったデプロイについては、ネット上であまり情報が見当たらず、デプロイにはCloudFormationを使用するのが主流かもしれません。

そこで、~~（しんどいので）~~ あえてCloudFormationを使わずに、CodePipelineを活用したデプロイに挑戦します。本記事の目的は、CodePipelineを使用する手順を解説することであり、設定内容の妥当性については評価の対象外とします。

なお、Lambdaをデプロイするだけなら、CodeBuildだけで十分に対応可能ですが、CodeDeployを利用することで、より高度なデプロイプロセスを実現しようと試行錯誤しました。

追記）Qiitaで検索すると結構記事が見つかった。
https://qiita.com/search?q=Lambda%E3%82%92CodePipeline%E3%81%A7%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%81%99%E3%82%8B


## まずはテリーの新動画が出たので見ましょう。9/24テリー発売です。

<iframe width="2283" height="1010" src="https://www.youtube.com/embed/i4x6ovIO7Kk" title="『ストリートファイター6』キャラクターガイド｜テリー（Terry）" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>



## 構成図

これに近い。

https://qiita.com/tech4anyone/items/59fd14a4553e365296bd#aws-codedeploy-for-lambda

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/459afe41-322b-0514-a2ff-ad2f97d0d9a8.png)


違い
- 承認者はいない（がプルリクエストをするなら承認者の運用は可能）
- Lambdaのエンドポイントは開発用と本番用で分けた（ここだけオリジナルで工夫した）

## 利用するリージョン
どこでもいいですが、`ap-northeast-1`とする。検証で軽く使う分にはどこを使っても差はコストに差は出ない。

## AWS CLIインストール
### 用途
API Gatewayの権限設定で必要になるので、インストールしておく。

### AWS CLIインストール方法(Windows)
https://qiita.com/nonZy/items/c3c0116445883c088bb2


## 本手順を読むときの注意事項
- バケット名は一意となる名前が必要なので手順そのままは使えないと思います。バケット名、ロール名、パイプライン名等の名前の設定では`zangief`という文字を使っています。そのためこの部分を自分の好きな名前に変えれば困らないと思います。

## IAMロールの作成

### 用途
- CodeDeploy用のロールを作ります
### 作成手順
1. 「ロールを作成」をクリックし、以下の設定内容でロールを作成します。

    | 画面名                       |                               | 項目                       | 設定値                               | 
    | ---------------------------- | ----------------------------- | -------------------------- | ------------------------------------ | 
    | 信頼されたエンティティを選択 | 信頼されたエンティティタイプ  | -                          | AWS のサービス                       | 
    |                              | ユースケース                  | サービスまたはユースケース | Lambda                               | 
    | 許可を追加                   | 許可ポリシー                  |                            | AmazonS3FullAccess                   | 
    |                              |                               |                            | AWSCodeDeployRole                    | 
    |                              |                               |                            | AWSCodeDeployRoleForLambda           | 
    |                              | 許可の境界を設定 - オプション |                            | -                                    | 
    | 名前、確認、および作成       | ロールの詳細                  | ロール名                   | test-codedeploy-zangief-service-role | 
    |                              |                               | 説明                       | -                                    | 
    |                              | 信頼ポリシー                  | -                          | -                                    | 
    |                              | 許可ポリシーの概要            | -                          | -                                    | 
    |                              | タグを追加 - オプション       | -                          | -                                    | 


1. ポリシーを追加
IAM→ロール→`test-codedeploy-zangief-service-role`を検索→許可タブ→許可を追加→ポリシーをアタッチ→`AmazonS3FullAccess`

### TODO
不要なポリシーもあるかも。精査せずとりあえずFullAccessを与えてるので、過剰だとは思う

## S3バケットの作成

### 用途
- CodeBuildでlambda.zipを保存。lambda.zipにはラムダ本体のプログラムファイル（`lambda_function.py`）が入ってます。ラムダのアップデートするときはzipにする必要があります。

### 作成手順
「バケットを作成」をクリックし、以下の設定内容でバケットを作成します。

| バケットを作成 | 一般的な設定                                 | バケットタイプ                              | 汎用                                                                                                                   | 
| -------------- | -------------------------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | 
|                |                                              | バケット名                                  | test-codepipeline-zangief                                                                                              | 
|                |                                              | 既存のバケットから設定をコピー - オプション | -                                                                                                                      | 
|                | オブジェクト所有者                           | -                                           | ACL 無効 (推奨)                                                                                                        | 
|                | このバケットのブロックパブリックアクセス設定 | -                                           | 「パブリックアクセスをすべて ブロック」のチェックを入れる                                                                | 
|                | バケットのバージョニング                     | バケットのバージョニング                    | 有効にする<br>※今回は必要ないのだが、S3にファイル設置を契機にパイプラインを動かすときに必要な設定なので、設定しておく                                                                                                             | 
|                | タグ - オプション (0)                        | -                                           | -                                                                                                                      | 
|                | デフォルトの暗号化                           | 暗号化タイプ                                | Amazon S3 マネージドキーを使用したサーバー側の暗号化 (SSE-S3)                                                          | 
|                |                                              | バケットキー                                | 有効にする                                                                                                             | 
|                | 詳細設定                                     | オブジェクトロック                          | 無効にする                                                                                                             | 



以下の解説が詳しいです

https://zenn.dev/tomoshimizu/articles/7731679428b9d2

## CodeCommit（リポジトリ）の作成
### 用途
- デプロイに必要なコードを管理（保存）します。
### 作成手順

「リポジトリを作成」をクリックし、以下の設定内容でリポジトリを作成します。

| 画面名           |                  | 項目                | 設定値                                                                                       | 
| ---------------- | ---------------- | ------------------- | -------------------------------------------------------------------------------------------- | 
| リポジトリを作成 | リポジトリの設定 | リポジトリ名        | test-codepipeline-zangief                                                                    | 
|                  |                  | 説明 - オプショナル | -                                                                                            | 
|                  |                  | タグ                | -                                                                                            | 
|                  |                  | 追加設定            | -                                                                                            | 
|                  |                  | -                   | 「Amazon CodeGuru Reviewer for Java and Python を有効にする - オプショナル」のチェックを外す | 

以下のコードを登録する。今回は画面のUI上から登録する。
- buildspec.yml
    ```yaml:buildspec.yml
    version: 0.2
    
    env:
      variables:
        LAMBDA_FUNCTION_NAME: "test-hello-world-zangief"  # Lambda関数名を変数として定義
    
    phases:
      install:
        commands:
          - aws --version
    
      build:
        commands:
          - echo Build started on `date`
          - zip -r lambda.zip lambda_function.py
          - aws lambda update-function-code --function-name $LAMBDA_FUNCTION_NAME --zip-file fileb://lambda.zip
          - sleep 10 # wait for update-function-code complete
          - aws lambda publish-version --function-name $LAMBDA_FUNCTION_NAME --description "update version"
          # 今回は扱わないが、prodを最新バージョンに切り替える場合は以下のようにすればOK
          # - NEW_VERSION=$(aws lambda publish-version --function-name $LAMBDA_FUNCTION_NAME --description "update version" --query 'Version' --output text)
          # - aws lambda update-alias --function-name $LAMBDA_FUNCTION_NAME --name prod --function-version $NEW_VERSION
    
    artifacts:
      files:
        - lambda.zip
        - appspec.yml
    ```

- appspec.yml
    ```yaml:appspec.yml
    version: 0.0
    
    Resources:
      - MyLambdaFunction:
          Type: AWS::Lambda::Function
          Properties:
            Name: "test-hello-world-zangief"
            Alias: "prod"
            CurrentVersion: "1" # prod（エイリアス）が指すバージョン
            TargetVersion: "2" # 新しいバージョン、これに切り替えるということ
    
    # prodの指すバージョンが間違ってたりすると以下のエラーになるので注意
    # The deployment failed because the AppSpec file that specifies the AWS Lambda deployment configuration is missing or has an invalid configuration. 
    # The input AppSpec file is a not well-formed yaml. The template cannot be parsed.
    # CurrentVersion と TargetVersionが同じでもエラーにならない。デプロイを動かしたいだけなら同じにしておけばよい。
    ```
- lambda_function.py
    ```python:lambda_function.py
    import json

    def lambda_handler(event, context):
        # TODO implement
        return {
            'statusCode': 200,
            'body': json.dumps('this is the dev environment.')
        }
    ```

## Lambdaの作成
### 用途
- ラムダを使いたいので使う。ラムダ本体の作りはメッセージを表示する程度のものです。
### 作成手順

1. 「関数の作成」をクリックし、以下の設定内容で関数（lambda）を作成します。

    | 画面名     |              | 項目                                                                 | 設定値                   | 
    | ---------- | ------------ | -------------------------------------------------------------------- | ------------------------ | 
    | 関数の作成 | -            | -                                                                    | 一から作成               | 
    |            | 基本的な情報 | 関数名                                                               | test-hello-world-zangief | 
    |            |              | ランタイム                                                           | Python 3.12              | 
    |            |              | アーキテクチャ                                                       | x86_64                   | 
    |            |              | アクセス権限                                                         | -                        | 
    |            |              | デフォルトの実行ロールの変更                                         | -                        | 
    |            | 詳細設定     | -                                                                    | -                        |
    
1. コードを修正→保存(ctrl + s)→Deployをクリックする
    ```python:lambda_function.py
    import json

    def lambda_handler(event, context):
        # TODO implement
        return {
            'statusCode': 200,
            'body': json.dumps('this is the prod environment.')
        }
    ```

1. 「バージョン」タブ→「新しいバージョンを発行」をクリックし、新しいバージョンを発行します。

    | 画面名                                     | 項目                          | 設定値 | 
    | ------------------------------------------ | ----------------------------- | ------ | 
    | $LATEST から新しいバージョンを発行します。 | バージョンの説明 - オプション | -      | 

    バージョン１が発行されます。

1. コードを修正→保存(ctrl + s)→Deployをクリックする
    ```python:lambda_function.py
    import json

    def lambda_handler(event, context):
        # TODO implement
        return {
            'statusCode': 200,
            'body': json.dumps('this is the dev environment.')
        }
    ```

1. 「バージョン」タブ→「新しいバージョンを発行」をクリックし、新しいバージョンを発行します。

    | 画面名                                     | 項目                          | 設定値 | 
    | ------------------------------------------ | ----------------------------- | ------ | 
    | $LATEST から新しいバージョンを発行します。 | バージョンの説明 - オプション | -      | 

    バージョン２が発行されます。

1. 「エイリアス」タブ→「エイリアス作成」をクリックし、以下の設定内容でエイリアスを作成します。エイリアスは２つ作ります。`$LATEST`はバージョン２を指すことになります。（発行している最新バージョンを指す意味となります。バージョンが６つあれば、`$LATEST`は６を指します）

    | 画面名           |                | 項目              | 設定値  | 
    | ---------------- | -------------- | ----------------- | ------- | 
    | エイリアスを作成 | エイリアス設定 | 名前              | dev     | 
    |                  |                | 説明 - オプション | -       | 
    |                  |                | バージョン        | `$LATEST` | 
    |                  |                | 加重エイリアス    | -       | 
    |                  | エイリアス設定 | 名前              | prod    | 
    |                  |                | 説明 - オプション | -       | 
    |                  |                | バージョン        | 1       | 
    |                  |                | 加重エイリアス    | -       | 

    こうなっていればOK
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/5277124f-841c-ce75-f101-01f2881718b1.png)


### 動作確認

まだこの段階ではできません。API Gatewayの設定が必要です。

## API Gatewayの作成
### 用途
- 作ったラムダを実行するにはこれが必要。

### 作成手順

1. 「APIを作成」をクリックし、以下の設定内容でAPI Gatewayを作成します。

    | 画面名           |            | 設定値                   | 設定値                       | 
    | ---------------- | ---------- | ------------------------ | ---------------------------- | 
    | API タイプを選択 | -          | -                        | REST API                     | 
    | REST API を作成  | API の詳細 | -                        | 新しい API                   | 
    |                  |            | API 名                   | test-hello-world-zangief-api | 
    |                  |            | 説明 - オプション        | -                            | 
    |                  |            | API エンドポイントタイプ | -                            | 


1. 「リソース作成」をクリックし、以下の設定内容でリソースを作成します。

    | 画面名         |                | 項目               | 設定値                                                 | 
    | -------------- | -------------- | ------------------ | ------------------------------------------------------ | 
    | リソースを作成 | リソースの詳細 | プロキシのリソース | 無効（左に〇が寄っていればOK）                         | 
    |                |                | リソースパス       | /                                                      | 
    |                |                | リソース名         | test                                                   | 
    |                |                | -                  | 「CORS (クロスオリジンリソース共有」のチェックを入れる | 

    ※`「CORS (クロスオリジンリソース共有」`は今回は使わないけど、今後の設定で使うのでつけておくよ。

1. 「メソッドを作成」をクリックし、以下の設定内容でメソッドを作成します。

    | 画面名         |                            | 項目                | 設定値                                                                                              | 
    | -------------- | -------------------------- | ------------------- | --------------------------------------------------------------------------------------------------- | 
    | メソッドを作成 | メソッドの詳細             | メソッドタイプ      | GET                                                                                                 | 
    |                |                            | 統合タイプ          | Lambda 関数                                                                                         | 
    |                |                            | Lambda プロキシ統合 | 無効（左に〇が寄っていればOK）                                                                      | 
    |                |                            | Lambda 関数         | arn:aws:lambda:ap-northeast-1:XXXXXXXXXXX:function:test-hello-world-zangief:${stageVariables.alias} | 
    |                |                            | 統合のタイムアウト  | 29000                                                                                               | 
    |                | メソッドリクエストの設定   | -                   | -                                                                                                   | 
    |                | URL クエリ文字列パラメータ | -                   | -                                                                                                   | 
    |                | HTTP リクエストヘッダー    | -                   | -                                                                                                   | 
    |                | リクエスト本文             | -                   | -   |

    許可の追加コマンドサンプル。id等は個々で違うので画面に出てきたものを使ってね。`${stageVariables.alias}`はdevとprodに読み替えてね。ここはPowerShellからコマンド実行するよ。aliasの運用するとこの操作が必要なようだ。
    ```bash
    # PowerShell
    # dev用
    $ aws lambda add-permission `
    --function-name "arn:aws:lambda:ap-northeast-1:XXXXXXXXXX:function:test-hello-world-zangief:dev" `
    --source-arn "arn:aws:execute-api:ap-northeast-1:XXXXXXXXXX:ghl87hy91k/*/GET/test" `
    --principal apigateway.amazonaws.com `
    --statement-id 9f349d02-95e1-4ac1-a25e-dd9b99a2a8d6 `
    --action lambda:InvokeFunction

    # prod
    $ aws lambda add-permission `
    --function-name "arn:aws:lambda:ap-northeast-1:XXXXXXXXXX:function:test-hello-world-zangief:prod" `
    --source-arn "arn:aws:execute-api:ap-northeast-1:XXXXXXXXXX:ghl87hy91k/*/GET/test" `
    --principal apigateway.amazonaws.com `
    --statement-id 9f349d02-95e1-4ac1-a25e-dd9b99a2a8d6 `
    --action lambda:InvokeFunction
    ```
    
1. 「APIをデプロイ」をクリックし、以下の設定内容でAPIをデプロイします。

    | 画面名     | 項目                 | 設定値         | 
    | ---------- | -------------------- | -------------- | 
    | Deploy API | ステージ             | 新しいステージ | 
    |            | ステージ名           | dev            | 
    |            | デプロイメントの説明 | -              | 
    | Deploy API | ステージ             | 新しいステージ | 
    |            | ステージ名           | prod           | 
    |            | デプロイメントの説明 | -              | 


1. 左メニューの「ステージ」をクリックし、以下の設定内容でステージ変数を作成します。
    devを選択→ステージ変数タブをクリック

    | 画面名             | 項目 | 設定値 | 
    | ------------------ | ---- | ------ | 
    | ステージ変数を追加 | 名前 | alias  | 
    |                    | 値   | dev    | 

    prodを選択→ステージ変数タブをクリック

    | 画面名             | 項目 | 設定値 | 
    | ------------------ | ---- | ------ | 
    | ステージ変数を追加 | 名前 | alias  | 
    |                    | 値   | prod    | 

    こうなっていればOK。（prodも同様）
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/dbf4a7e6-3190-3c6f-bf2e-b97447ee44e0.png)


### 動作確認

1. ブラウザで以下にアクセスする。URLはAPI GATEWAYの画面に表示されてます
https://XXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/test

1. `{"statusCode": 200, "body": "\"this is the dev environment.\""}`が表示されればOK。これが開発環境用の動作確認となります。

1. ブラウザで以下にアクセスする
https://XXXXX.execute-api.ap-northeast-1.amazonaws.com/prod/test

1.  `{"statusCode": 200, "body": "\"this is the prod environment.\""}`が表示されればOK。これが本番環境用の動作確認となります。


## CodeBuildの作成
※単体ではpush契機で動作しない
### 用途
- ラムダ本体のアップデート
- appspec.ymlをS3バケットにアップロード

### 作成手順

1. 「プロジェクトを作成」をクリックし、以下の設定内容でプロジェクトを作成します。

    | 画面名                       |                    | 項目                                        | 設定値                                                                  | 
    | ---------------------------- | ------------------ | ------------------------------------------- | ----------------------------------------------------------------------- | 
    | ビルドプロジェクトを作成する | プロジェクトの設定 | プロジェクト名                              | test-codebuild-zangief                                                  | 
    |                              |                    | 追加設定                                    | -                                                                       | 
    |                              | ソース             | ソースプロバイダ                            | AWS CodeCommit                                                          | 
    |                              |                    | リポジトリ                                  | test-codepipeline-zangief                                               | 
    |                              |                    | リファレンスタイプ                          | ブランチ                                                                | 
    |                              |                    | ブランチ                                    | main                                                                    | 
    |                              |                    | コミット ID - オプショナル                  | -                                                                       | 
    |                              | 環境               | 環境イメージ                                | マネージド型イメージ                                                    | 
    |                              |                    | コンピューティング                          | Lambda                                                                  | 
    |                              |                    | オペレーティングシステム                    | Amazon Linux                                                            | 
    |                              |                    | ランタイム                                  | Python                                                                  | 
    |                              |                    | イメージ                                    | 最新を選ぶ（今回はx86_64用を選んでね）                                  | 
    |                              |                    | イメージのバージョン                        | -                                                                       | 
    |                              |                    | サービスロール                              | 新しいサービスロール                                                    | 
    |                              |                    | ロール名                                    | codebuild-test-codebuild-zangief-service-role<br>※自動で入力されてます | 
    |                              |                    | 追加設定                                    | -                                                                       | 
    |                              | Buildspec          | ビルド仕様                                  | buildspec ファイルを使用する                                            | 
    |                              |                    | ビルドコマンド                              | -                                                                       | 
    |                              |                    | Buildspec 名 - オプショナル                 | buildspec.yml                                                           | 
    |                              | バッチ設定         | -                                           | -                                                                       | 
    |                              | アーティファクト   | タイプ                                      | Amazon S3                                                               | 
    |                              |                    | バケット名                                  | test-codepipeline-zangief                                               | 
    |                              |                    | 名前                                        | deploy-artifacts                                                        | 
    |                              |                    | セマンティックバージョニングの有効化        | チェックを入れない                                                      | 
    |                              |                    | パス - オプショナル                         | -                                                                       | 
    |                              |                    | 名前空間のタイプ - オプショナル             | なし                                                                    | 
    |                              |                    | アーティファクトのパッケージ化              | なし                                                                    | 
    |                              |                    | アーティファクト暗号化の削除                | チェックを入れない                                                      | 
    |                              |                    | 追加設定                                    | -                                                                       | 
    |                              | ログ               | CloudWatch Logs - オプショナル              | チェックを入れる                                                        | 
    |                              |                    | グループ名 - オプショナル                   | -                                                                       | 
    |                              |                    | ストリーム名のプレフィックス - オプショナル | -                                                                       | 
    |                              |                    | S3 ログ - オプショナル                      | チェックを入れない                                                      | 

1. ロールにlambdaのポリシーをアタッチします。
IAM→ロール→`codebuild-test-codebuild-zangief-service-role`を検索→許可タブ→許可を追加→ポリシーをアタッチ→`AWSLambda_FullAccess`、`AWSLambda_FullAccess`

1. 「ビルドを開始」をクリックします
ビルドが成功するはずです。

    ビルドをするたびにバージョンは増加します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/ec77381e-a895-e32b-ffe9-ec1a579cd5d9.png)


### memo
- ロール：`CodeBuildBasePolicy-test-codebuild-zangief-ap-northeast-1`が自動生成される。CodeBuildを作り直す場合は、削除が必要。
- ポリシー：`codebuild-test-codebuild-zangief-service-role`が自動生成される。CodeBuildを作り直す場合は、削除が必要。


## CodeDeployの作成
※単体ではpush契機で動作しない
### 用途
- 本番環境のラムダを指定したバージョンにアップデートする。
- `appspec.yml`はS3にアップロードされたものを使っています。このアップロードはCodeBuildのArtifactの設定で行っています。CodeCommitから`appspec.yml`を取得する機能はない（はず）。ここで結構はまりました。

### 作成手順

1. 「アプリケーションの作成」をクリックし、以下の設定内容でアプリケーションを作成します。

    | 画面名                 |                        | 項目                               | 設定値                  | 
    | ---------------------- | ---------------------- | ---------------------------------- | ----------------------- | 
    | アプリケーションの作成 | アプリケーションの設定 | アプリケーション名                 | test-codedeploy-zangief | 
    |                        |                        | コンピューティングプラットフォーム | AWS Lambda              | 
    |                        |                        | タグ                               | -                       | 

1. 「デプロイグループの作成」をクリックし、以下の設定内容でデプロイグループを作成します。

    | 画面名                 |                    | 項目                     | 設定値                            | 
    | ---------------------- | ------------------ | ------------------------ | --------------------------------- | 
    | デプロイグループの作成 | アプリケーション   | アプリケーション名       | -                                 | 
    |                        |                    | コンピューティングタイプ | 
    |                        | -                  | 
    |                        | デプロイグループ名 | デプロイグループ名の入力 | test-codedeploy-zangief-group     | 
    |                        | サービスロール     | サービスロールの入力     | CodeDeployServiceRole             | 
    |                        | デプロイ設定       | デプロイ設定             | CodeDeployDefault.LambdaAllAtOnce | 
    |                        | 詳細 – オプション | -                        | -                                 | 


1. 「デプロイの作成」をクリックし、以下の設定内容でデプロイを作成します。

    | 画面名            |                                  | 項目                               | 設定値                                                      | 
    | ----------------- | -------------------------------- | ---------------------------------- | ----------------------------------------------------------- | 
    | Create deployment | デプロイ設定                     | アプリケーション                   | -                                                           | 
    |                   |                                  | デプロイグループ                   | test-codedeploy-zangief-group                               | 
    |                   |                                  | コンピューティングプラットフォーム | -                                                           | 
    |                   |                                  | デプロイタイプ                     | -                                                           | 
    |                   |                                  | リビジョンタイプ                   | アプリケーションは Amazon S3 に格納されています             | 
    |                   |                                  | リビジョンの場所                   | s3://test-codepipeline-zangief/deploy-artifacts/appspec.yml | 
    |                   |                                  | リビジョンファイルの種類           | .yaml                                                       | 
    |                   | デプロイの説明                   | デプロイの説明: オプション         | -                                                           | 
    |                   | デプロイグループのオーバーライド | -                                  | -                                                           | 
    |                   | ロールバック設定の上書き         | -                                  | -                                                           | 


1. デプロイが成功することを確認します。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/0fddb5fc-6db9-a8ed-713d-cefb813d070b.png)

1. ブラウザで以下にアクセスする
https://XXXXX.execute-api.ap-northeast-1.amazonaws.com/prod/test

1.  `{"statusCode": 200, "body": "\"this is the dev environment.\""}`が表示されればOK。**devと表示されますが、バージョン２のプログラムはdevとなっているので問題ありません。prodと表示されるのはバージョン１のみです。** prodと表示したければそのバージョンを用意して、そのバージョンに切り替えればOKです。


## CodePipelineの作成

### 用途
- CodeBuildとCodePipelineを連動させます。またCodeCommitにコードをpushすると動き出します
### 作成手順

1. 「パイプラインを作成」をクリックし、以下の設定内容でパイプラインを作成します。

    | 画面名                       |                         | 項目                                                                                                          | 値                                                                      | 
    | ---------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | 
    | パイプラインの設定を選択する | パイプラインの設定      | パイプライン名                                                                                                | test-codepipeline-zangief                                               | 
    |                              |                         | パイプラインタイプ                                                                                            | キュー (パイプラインタイプ V2 が必須)                                   | 
    |                              |                         | サービスロール                                                                                                | 新しいサービスロール                                                    | 
    |                              |                         | ロール名                                                                                                      | test-codepipline-zangief-service-role<br>※自動入力される名前を修正する | 
    |                              |                         | AWS CodePipeline がサービスロールを作成できるようになるため、この新しいパイプラインでの使用が可能になります。 | チェックを入れる                                                        | 
    |                              | 変数                    | -                                                                                                             | -                                                                       | 
    |                              | 高度な設定              | アーティファクトストア                                                                                        | カスタムロケーション                                                    | 
    |                              |                         | バケット                                                                                                      | test-codepipeline-zangief                                               | 
    |                              |                         | 暗号化キー                                                                                                    | デフォルトの AWS マネージド型キー                                       | 
    | ソースステージを追加する     | ソース                  | ソースプロバイダー                                                                                            | AWS CodeCommit                                                          | 
    |                              |                         | リポジトリ名                                                                                                  | test-codepipeline-zangief                                               | 
    |                              |                         | ブランチ名                                                                                                    | main                                                                    | 
    |                              |                         | 検出オプションを変更する                                                                                      | Amazon CloudWatch Events (推奨)                                         | 
    |                              |                         | 出力アーティファクト形式                                                                                      | CodePipeline のデフォルト                                               | 
    | ビルドステージを追加する     | 構築する - オプショナル | プロバイダーを構築する                                                                                        | AWS CodeBuild                                                           | 
    |                              |                         | リージョン                                                                                                    | アジアパシフィック（東京）                                              | 
    |                              |                         | 入力アーティファクト                                                                                          | SourceArtifact                                                          | 
    |                              |                         | プロジェクト名                                                                                                | test-codebuild-zangief                                                  | 
    |                              |                         | 環境変数 - オプショナル                                                                                       | -                                                                       | 
    |                              |                         | ビルドタイプ                                                                                                  | 
    |                              | 単一ビルド              | 
    | デプロイステージを追加する   | デプロイ - オプショナル | デプロイプロバイダー                                                                                          | AWS CodeDeploy                                                          | 
    |                              |                         | リージョン                                                                                                    | アジアパシフィック（東京）                                              | 
    |                              |                         | 入力アーティファクト                                                                                          | BuildArtifact                                                           | 
    |                              |                         | アプリケーション名                                                                                            | test-codedeploy-zangief                                                 | 
    |                              |                         | デプロイグループ                                                                                              | test-codedeploy-zangief-group                                           | 
    |                              |                         | ステージ障害時の自動ロールバックを設定                                                                        | チェックを入れない                                                      | 

1. デプロイが成功することを確認します。**ですが、ここは失敗するはずです。`appspec.yml`の`CurrentVersion`と`TargetVersion`を適切な値に修正して、再度実行しましょう。**

    ※S3_triggerは次の「おまけ」を実施しないと表示されません
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/040cfd2c-fdea-501c-c521-6af9f311dca3.png)


    ```yaml:修正版appspec.yml
    version: 0.0
    
    Resources:
      - MyLambdaFunction:
          Type: AWS::Lambda::Function
          Properties:
            Name: "test-hello-world-zangief"
            Alias: "prod"
            CurrentVersion: "2" # prod（エイリアス）が指すバージョン
            TargetVersion: "3" # 新しいバージョン、これに切り替えるということ
    ```

### おまけ（任意）
意味はないが、S3に何かデータを置いたら動作するようにもしたい。

以下の画像のようにS3_triggerというのを追加してみた。これでS3にtest.txtを設置または、CodeCommitのファイルを更新するとパイプラインが先頭から動き出す。通常の運用でSourceのアクショングループが2種類あることは少ないと思う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/e03ce040-8d74-c85c-4a50-561362a2e49c.png)

| 画面名 |     | 項目                                    | 値                              | 
| ------ | --- | --------------------------------------- | ------------------------------- | 
|        |     | アクション名                            | S3_trigger                      | 
|        |     | アクションプロバイダー                  | Amazon S3                       | 
|        |     | バケット                                | test-codepipeline-zangief       | 
|        |     | S3 オブジェクトキー                     | test.txt                        | 
|        |     | 検出オプションを変更する - オプショナル | Amazon CloudWatch Events (推奨) | 
|        |     | 変数の名前空間 - オプショナル           | -                               | 
|        |     | 出力アーティファクト                    | S3_Artifact                     | 

## トラブルシューティング
- codedeployではappspec.ymlを使うのですが、prodのバージョン等のバージョンの設定を間違えるとビルドがこけます。エラーメッセージが分かりづらいです。

    ```bash
    # 例
    The deployment failed because the AppSpec file that specifies the AWS Lambda deployment configuration is missing or has an invalid configuration. The Lambda function alias version does not match the current version in AppSpec file.
    ```

- appspec.ymlで、ラムダのデプロイの前後処理でシェルスクリプトは実行できません。実行できるのはラムダのみ。シェルスクリプトはEC2のデプロイのときにしかできないと思われる。マニュアルにはシェルスクリプトは実行できないとは書いてないが、ラムダは実行できるとちゃんと書いてあります。AI(ChatGpt）は実行できると思ってるので、かなりこれではまりました。

## Lambdaバージョン管理の運用方法
- **dev（開発環境）** と**prod（本番環境）** ではラムダ本体のプログラム（`lambda_function.py`）は同じですが、エンドポイントは微妙に異なります。
- **dev（開発環境）** では、`lambda_function.py`を更新するたびに、CodePipeline（CodeBuild）を実行して変更を反映させます。これで日々の開発作業ができるはずです。

- **prod（本番環境）** では、`appspec.yml`で明示的に目的のLambdaのバージョンを指定し、CodePipeline（CodeDeploy）を実行するたびに反映されます。バージョンを変更しない限り、日々の開発で本番環境に影響が出ません。ただし、バージョン指定が誤っていたり、連続デプロイをするとエラーがおきます。業務ではプルリクエストを使用してコードをマージするため、必ず確認作業（承認作業）が入ります。そのため、勝手に本番環境が更新されることはありません。とはいえ、面倒ですがDeploy処理は本番反映するときのみ有効にした方がいいですね。イケてないので、この運用ではダメでしょう。（おそらくパイプラインを開発環境（CodeBuildのみ）と本番環境（CodeDeployのみ）で分割すれば問題は解消するでしょう）

    「移行を無効にする」をクリック
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/f06600e5-3779-8041-dfa2-0abb56f11481.png)


## さいごに
- この手順を実施すれば、CodePipelineはおそらく動作すると思いますが、最初から最後まで一貫して通しで行ったわけではありません。

- まだ書きたいことはありますが、少し疲れてきたので、ひとまずここまでとします。応用編も試してみましたが、執筆が大変なので途中で止めることにしました。

- 手作業でこれだけの運用作業を正確に実施するのは無理だと思いましたので、業務では積極的にCloudFormationを使いましょう。

- ラムダのバージョン管理、ラムダのところが初見では難しいと思います。ページ末尾に参考リンク集を用意したのでそちらをみて理解を深めましょう。

- ネットの記事を見るとAWSのUIのレイアウトが今と違うものが多くて苦労しました。

- AWSのマニュアルは、読みづらいと感じました。途中で読むのを諦めてしまいました。

- AI（ChatGpt）を使ってみましたが、応答は遅いし、細かい部分の説明が不十分で、間違いも多かったです。~~金返せ~~

- 今回の活動で結構AWSの知識が身についたと感じています。もう少し頑張って引退しようと思います。


# 応用編

## CloudFrontの作成
### 用途
### 作成手順
### 動作確認

## WAFの作成
### 用途
### 作成手順
### 動作確認

## Route53の作成
### 用途
### 作成手順
### 動作確認

## ACMの作成
### 用途
### 作成手順
### 動作確認

## CloudForamationの作成
全部はしんどいので、ラムダ周りを
### 用途
### 作成手順
### 動作確認

## Batchの作成
### 用途
### 作成手順
### 動作確認

## 参考資料

https://qiita.com/Gethe/items/d4629edd6fe142f81a63


https://qiita.com/tech4anyone/items/59fd14a4553e365296bd

https://cloud5.jp/lambda-autodeploy-used-codepipeline/

https://qiita.com/lunar_sword3/items/d8f738fa0662802163f3

https://dev.classmethod.jp/articles/version-management-with-api-gateway-and-lambda/

https://qiita.com/jianyi/items/05c83fc232af73f9fe3a