CodePipelineのチュートリアルやってみた！～S3編～

# はじめに
DOPの試験を受けた際にCodePipelineにたくさんお目にかかったので、どうせなら触ってみようとチュートリアルをやることにしました。

# やってみる
今回は「<a href="https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/tutorials-simple-s3.html">チュートリアル: シンプルなパイプラインを作成する (S3 バケット)</a>」をやってみました。

## 事前準備
実際にパイプラインを作成するにあたり、<a href=https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/getting-started-codepipeline.html>こちらの記事</a>を参考に作業用のIAMユーザを作成します。
記事では`AWSCodePipeline_FullAccess`を最低限与えると書かれていますが、このチュートリアルを行うにあたり以下のポリシーも割り当てた方がいいと思います。
* `IAMFullAccess`
* `AWSCodeDeployFullAccess`
* `AmazonS3FullAccess`
* `AmazonEC2FullAccess`

また、カスタムマネージドポリシーで、Systems Managerに対する以下のポリシーも必要です。
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ssm:CreateAssociation",
            "Resource": "*"
        }
    ]
}
```

## 1. S3にバケットを作成する
このチュートリアルでは、S3からEC2インスタンスに対しデプロイを行う内容となっています。
私はWindowsサーバに対しデプロイを行う方法を選択しました。

まずはデプロイするソースファイルをS3に配置します。
S3でバージョニングを有効にしたバケットを作成し（アクセス許可はデフォルトのままにします）、<a href="https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/samples/SampleApp_Windows.zip">こちらのWindows用のリンク</a>からzipファイルを手元にダウンロードしてバケットにアップロードします。

zipファイルの中には、
* appspec.yml
* デプロイ前に実行されるbatファイル
* index.html
* LISENCE

の4つが含まれています。

`appspec.yml`はCodeDeployでデプロイを行う際の定義ファイルで、サーバのどこにどのファイルを配置するか、デプロイの際にどのようなアクションを行うかなどが定義できます。

batファイルではIISのインストールを行うコマンドが書かれています。

## 2. EC2インスタンスにアタッチするIAMロールを作成する
EC2インスタンスにIAMロールをアタッチする必要があるので、先にロールを作成します。
IAMロールに含めるポリシーは以下の２つです。
* `AmazonSSMManagedInstanceCore`
* `AmazonEC2RoleforAWSCodeDeploy`

## 3. EC2インスタンスを作成する
次にデプロイ先となるEC2インスタンスを作成します。

今回はパブリックなインスタンスを2台作成するので、事前にVPC、サブネット、IGW、ルートテーブルを作成しておきましょう。


インスタンスは下記の設定で作成しました。
* AMI: `Microsoft Windows Server 2019 Base`
* インスタンスタイプ: `t2.micro`
* パブリック IP の自動割り当て: `有効`

ほかのマシンイメージでも恐らくできますが、SSMエージェントがプリインストールされているイメージを選んでください。

セキュリティグループは、`22(SSH)`、`80(HTTP)`、`3389(RDP)`のポートで、それぞれMyIPを許可するように設定しました。

また、高度な設定でIAM インスタンスプロフィールに先程作成したIAMロールを設定します。

## 4. CodeDeployでデプロイグループを作成する
インスタンスが起動出来たら、CodeDeployでデプロイグループを作成します。

デプロイグループを作成する前に、CodeDeployのサービスロールとアプリケーションを作成する必要があるので先にそちらを行います。

### サービスロール
サービスロールは、インスタンスに割り当てたIAMロールと同じように作成します。ユースケースで`CodeDeploy`を選択すると自動的に`AWSCodeDeployRole`ポリシーが含まれるようになるので、何もせず確認画面から作成を行います。

### アプリケーション
アプリケーションはCodeDeployコンソールに移動し、アプリケーションタブからアプリケーションの作成を行います。
***コンピューティングプラットフォーム***を選択するところでは`EC2/オンプレミス`を選択します。

### デプロイグループ
先程作成したアプリケーションの画面からデプロイグループの作成を行います。
* ***Service role***：先程作成したサービスロールを選択
* ***Deployment type***：`In-place`
* ***環境設定***：`EC2インスタンス`を選択し、キーの部分には`Name`、値の部分には***先程作成したインスタンス名***を入力。
インスタンスを作成する際につけた名前は、自動的に「Name: インスタンス名」というタグとしてインスタンスに付与されるので、これを指定します。
* ***AWSSystems Manager によるエージェント設定***：`今すぐアップデートをスケジュールする`
* ***デプロイ設定***：`CodeDeployDefault.OneAtaTime`
* ***ロードバランシングの有効化***：なし（チェックを外す）

この設定でデプロイグループを作成します。

## 5. CodePipelineでパイプラインを作成する
いよいよパイプラインの作成です。
CodePipelineコンソールからパイプラインの作成を選択します。

### パイプラインの設定を選択する
適当な名前を入力し、サービスロールの作成を選択します。
高度な設定は特に変更しません。

### ソースステージを追加する
ソースプロバイダーに`S3`を選択します。
バケットには１．で作成したバケット名を、S3 オブジェクトキーにはアップロードしたzipファイル名を（変更していなければ`SampleApp_Windows.zip`）を入力します。
検出オプションは特に変更せず、次に進みます。

### ビルドステージを追加する
こちらは`ビルドステージをスキップ`ボタンを押してスキップします。

### デプロイステージを追加する
デプロイプロバイダーに`CodeDeploy`を、アプリケーションとデプロイグループは4.で作成したものを選択します。

ここまで設定したらパイプラインを作成し、パイプラインの実行が完了するのを待ちます（数分かかります）。

## 完了
パイプラインが完了したら、インスタンスのパブリックDNS名をブラウザに入力しましょう！
画面に緑色のページが表示されれば成功です。

# できないときは
私はこのようなエラーメッセージが表示されました。
```
CodeDeploy agent was not able to receive the lifecycle event. Check the CodeDeploy agent logs on your host and make sure the agent is running and can connect to the CodeDeploy server.
```
上手くいかない場合は以下の項目をチェックしてみてください。

* IGWが存在しているか
* ルートテーブルは正しいか
* PublicIPが割り当てられているか
* SSMエージェントがインストールされているか
* セキュリティグループの設定は正しいか

# おわりに
CICDパイプラインを意外とあっさり組めたので、ほかのチュートリアルもチャレンジしてみます。

# 参考
* <a href="https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/tutorials-simple-s3.html">チュートリアル: シンプルなパイプラインを作成する (S3 バケット)</a>
* <a href="https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/reference-appspec-file-structure.html">AppSpec ファイル構造</a>