JavaによるLambdaをCodepipelineで自動リリースする最小構成サンプル

# TL;DR

以下の文書では、node.js でのLambda関数のリリースを自動化する例が出ています。
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/automating-deployment.html

本文書では、これとほぼ同じようなアプリをJavaで書き、そのリリースを自動化します。それぞれの要素の意味や役割の説明は最低限に留めます。 (筆者もよくわかってません。えっへん。) 最小の動作サンプルの例示を行います。

本文書ではマネージメントコンソール上で色々手作業で設定を入れさせています。今後のUIの変更で、手順が変わっているかもしれません。ご容赦を。

# 前提

- githubにコードが配置してあること。
- 更新を検出するブランチが決めてあること。
 - この例では、以下のURLのmasterブランチであるとします。https://github.com/kazurof/minimum-java-lambda-with-codepipeline サンプルコードもここに配置してあります。
- Gradleでビルドを行います。
- 中間ファイルを置くためのS3バケットがあること。例として、`auto-release-sample`とします。


# 準備

## ロールの作成

IAM マネージメントコンソールを開き、以下のようにロールを作成します。

| 項目                   | 値                                   | 備考                                                                                            |
|------------------------|--------------------------------------|-------------------------------------------------------------------------------------------------|
| 名前                   | cloudformation-lambda-execution-role |                                                                                                 |
| ロールタイプ           | AWS CloudFormation                   | 作成時は「AWS サービスロール」から選択する。作成後のロールの画面では、信頼関係 タブに表示される |
| アタッチされたポリシー | AWSLambdaExecute                     | ロールの画面では、アクセス許可 タブ＝＞管理ポリシー に表示される                                |

	
一度ロールを作った後、作成したロールをマネージメントコンソールで開き、`インラインポリシーの追加`をクリックする。　　`カスタムポリシー　－＞　選択` と進んだ後下記内容を記載する。ポリシー名は適宜設定する。

```
{
    "Statement": [
        {
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketVersioning"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::codepipeline*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:*"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:GetRole",
                "iam:CreateRole",
                "iam:DeleteRole"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "cloudformation:CreateChangeSet"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        }
    ],
    "Version": "2012-10-17"
}

```
注：必要最低限の権限になってはいないかもです。今後の本記事の更新でなるべく削って行きたいです。


# githubにファイルを配置する

アプリケーションのソースコードをgithubに保存します。

具体的なファイルの中身はサンプルリポジトリを参照してください。
https://github.com/kazurof/minimum-java-lambda-with-codepipeline
ファイルのディレクトリ構成を記載しておきます。

```
│  build.gradle
│  buildspec.yml
│  gradlew
│  gradlew.bat
│  minimum-lambda-java-model.yaml
│
│
├─gradle
│  └─wrapper
│          gradle-wrapper.jar
│          gradle-wrapper.properties
│
└─src
    └─main
        └─java
            └─codepipelinesample
                    Main.java
```

## 補足

`buildspec.yml` には、利用するS3リポジトリ名が記載されます。（先に、`auto-release-sample`としたもの。）実際に動かしてみる場合は適宜あなたが用意したリポジトリ名に変更してください。


# CodePipeline の作成

AWS CodePipeline のマネージメントコンソールを開き、パイプラインを以下のように作成する。

## パイプライン名

パイプライン名はわかればなんでも良い。

## ソース



| 項目                   | 値      | 備考                                                                                                                                                 |
|------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| ソースプロバイダ       | GitHub  | GitHubを選択すると、GitHubリポジトリのURLとブランチを指定し、OAuth認証を行い、CodePipelineから指定したGitHubのリポジトリにアクセスできるようにする。 |
| アクションカテゴリー   | ソース  | 作成時は入力を求められない。自動でつけられるものでOK                                                                                                 |
| アクション名           | Source  | 作成時は入力を求められない。自動でつけられる名前でOK                                                                                                 |
| 出力アーティファクト名 | MyApp   | 作成時は入力を求められない。自動でつけられる名前でOK                                                                                                 |


## ビルド

| 項目                 | 値            | 備考                         |
|----------------------|---------------|------------------------------|
| ビルドプロバイダ     | AWS CodeBuild |                              |
| アクションカテゴリー | ビルド        | 作成時は入力を求められない。 |
| アクション名         | CodeBuild     | 作成時は入力を求められない。 |


`CodeBuildの新しいプロジェクトを作る`を選択する。プロジェクト名はわかればなんでも良い。

### ビルドプロジェクトの作成


| 項目       | 値                                                      |
|------------|---------------------------------------------------------|
| ビルド環境 | Ubuntu Java8                                            |
| ビルド仕様 | ソースコードのルートディレクトリの buildspec.yml を使用 |


注：
- この時、AWS CodeBuild のサービスロールがユーザーに代わり自動的に作成されます。`code-build-＜ビルドプロジェクト名＞-service-role` という形になります。
- このビルドのアクションにおいて、以下項目が以下のように自動設定されます。

| 項目                 | 値         |
|----------------------|------------|
| 入力アーティファクト | MyApp      |
| 出力アーティファクト | MyAppBuild |

「ビルドプロジェクトの保存」を押下、「次のステップ」を押下してください。

## デプロイ



| 項目                 | 値                         | 備考                 |
|----------------------|----------------------------|----------------------|
| デプロイプロバイダ   | AWS CloudFormation         |                      |
| アクションモード     | 変更セットの作成または置換 |                      |
| スタックの名前       | MyBetaStack       | アクション名にも使われる。     |
| 変更セット名         | MyChangeSet       |                      |
| テンプレートファイル | packaged-minimum-lambda-java-model.yaml   |                |
| Capabilities（特徴） | CAPABILITY_IAM             |                      |
| ロール名           | cloudformation-lambda-execution-role   | この作業手順の先頭で作ったロールを指定する。     |
| アクションカテゴリー | デプロイ                   | 自動で設定される     |



## AWS サービスロールの作成

ロールを新たに作ります。

当該画面の文言を転載：
「AWS CodePipeline がアカウントでリソースを使用するアクセス許可を付与するため、IAM にサービスロールを作成します。」

- 「ロールの作成」を押下。
- 「許可」を押下。
- 「次のステップ」を押下。


ロール名は、「AWS-CodePipeline-Service」になるはずです。（すでにある場合はインラインポリシーに追加される挙動の様子。未確認です。）

## パイプラインの確認

今まで入力した内容の確認画面が表示される。「パイプラインの作成」を押下します。

# サービスロールを修正

Codebuild 向けに作成されたサービスロールが、用意したS3バケット（`auto-release-sample`）にアクセスできるように修正する。

今までの手順で、`code-build-＜ビルドプロジェクト名＞-service-role`なるロールが生成されているのでそれを修正する。


- IAM マネジメントコンソールから、ロール を選択する。
- `code-build-＜ビルドプロジェクト名＞-service-role`　を選択する。
- 「アクセス権限」タブ＝＞　「インラインポリシーの追加」　をクリックする。
- 「Policy Generator」 を選択して 「Select」 を選択する。
- 「AWS Service」 で、「Amazon S3」 を選択する。
- 「Actions」 で、「PutObject」 を選択する。
- 「Amazon Resource Name (ARN)」 に `arn:aws:s3:::auto-release-sample*` と入力する。（末尾のアスタリスク必要！）
- 「ステートメントを追加」 を押下して 「Next Step」 を押下する。
- 「ポリシーの適用」 を押下する。



# CodePipelineにLambdaを更新するステップを追加する

- AWS CodePipeline　マネジメントコンソールに移動　＝＞作成したpipelineを選択
- 編集ボタンをクリック
- Stagingの鉛筆アイコンをクリック
- 既存のアクションの最後にある [+ Action] アイコンを選択する。
- 以下のように入力

| 項目                 | 値                                          |
|----------------------|---------------------------------------------|
| アクションカテゴリー | デプロイ                                    |
| アクション名         | execute_cs  (わかればなんでも良い) |
| デプロイプロバイダ   | AWS CloudFormation                          |
| アクションモード     | 変更セットの実行                            |
| スタックの名前       | MyBetaStack                        |
| 変更セット名         | MyChangeSet                        |


- 「更新」を押して保存
- 「パイプラインの変更を保存」を押してパイプライン全体を保存


# 自動リリースとLambdaの実行

以上でCodepipeline 作成は終了です。gitリポジトリのmasterブランチに何か修正を入れてみてください。Codepipelineのマネジメントコンソールで、パイプラインが動作するところを確認できます。

正しく終了したら、Lambdaのマネージメントコンソールを開いてください。JavaによるLambda関数が作成されているはずです。テスト実行ができます。


# 感想

関係する要素技術多いせいか、手順長いですね。。。:sweat_smile: