aws protonを使って複数の開発環境を制御する



## 目的
IaCをterraformで進めており、AWS protonがterraformを活用した自己管理型プロビジョニング(自前のgithub actionでプロビジョニング)を提供しているので、活用することにした。

proton×terraform×githubaction間の連携がかなり複雑で公式の説明も概要レベルだったので、シーケンス図として整理した。

## 参考
- 自己管理型プロビジョニングについて
https://aws.amazon.com/jp/blogs/news/aws-proton-self-managed-provisioning/

- サンプルコード
    - AWSのサービスがHCLで記載されたサンプルコード
    https://github.com/aws-samples/aws-proton-terraform-sample-templates
    
    - 自己管理型プロビジョニングとして実行するgithub actionのサンプルコード
    https://github.com/aws-samples/aws-proton-terraform-github-actions-sample
    
    - 構築したAWS環境で動作するサンプルアプリケーションコード
    https://github.com/aws-samples/aws-proton-sample-services

## proton×terraform×githubaction間の連携について(全体図)

- AWS公式で公開されている概要図はこちら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606196/4bdb402a-6d34-003d-e769-4a8a7830e7fd.png)

- 詳細化したシーケンス図がこちら
![Screen Shot 2023-02-21 at 21.21.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606196/69385d80-ac04-ba19-5516-3a481924e944.png)

- protonから操作してテストアプリケーションの稼働が確認できるまでに主に５stepに分かれます。
(以下の数字は上記シーケンス図左端の丸番と一致しています。)
   　 1. protonに環境テンプレートとサービステンプレートを登録
   　 2. 環境テンプレートから環境をプロビジョニング
  　  3. サービステンプレートのうちサービスインスタンスをプロビジョニング
  　  4-前半. サービステンプレートのうちパイプラインをプロビジョニング
  　  4-後半. アプリケーションを最終版に更新

- 環境、サービスをプロビジョニングしたあとのaws-proton-terraform-github-actions-sampleの状態
  ```
    ~/aws-proton-terraform-github-actions-sample
    ├── env_config.json
    ├── pipeline  #パイプライン構築時に自動作成
    │   └── pipeline　
    │       ├── config.tf
    │       ├── data.tf
    │       ├── locals.tf
    │       ├── main.tf　＃ecr、codepipeline、、、
    │       ├── outputs.tf
    │       ├── proton.auto.tfvars.json
    │       └── proton.pipeline.variables.tf
    ├── testenv-fargate  #環境構築時に自動作成
    │   ├── config.tf
    │   ├── data.tf
    │   ├── locals.tf
    │   ├── main.tf　＃VPC
    │   ├── outputs.tf
    │   ├── pipeline-test-fargate  #サービスインスタンス構築時に自動作成
    │   │   ├── config.tf
    │   │   ├── data.tf
    │   │   ├── locals.tf
    │   │   ├── main.tf　＃ECS、ALB
    │   │   ├── outputs.tf
    │   │   ├── proton.auto.tfvars.json
    │   │   └── proton.service_instance.variables.tf
    │   ├── proton.auto.tfvars.json
    │   └── proton.environment.variables.tf
  ```

## 事前準備
aws-proton-terraform-github-actions-sampleが機能するためにgithubの認証やS3バケットの構築が必要。
cloudformationで用意されているため、aws-proton-terraform-github-actions-sampleのREADMeを参照。
https://github.com/aws-samples/aws-proton-terraform-github-actions-sample/blob/main/README.md



## proton×terraform×githubaction間の連携について(詳細)

### 1. protonに環境テンプレートとサービステンプレートを登録
![Screen Shot 2023-02-21 at 21.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606196/d5505492-e625-fa36-2cb9-944c33b97c79.png)

- 複数のサービスが含まれるテンプレートリポジトリの場合はディレクトリ名と一致させる必要がある。
    - 参考https://qiita.com/techiohanina/items/4571de942ad46c765c0d
- ディレクトリ名に誤りがあるとリポジトリ同期の際にエラーとなる。
- 同期させておくとテンプレートリポジトリを更新した際にproton側でもバージョンアップしてくれる。


### 2. 環境テンプレートから環境をプロビジョニング
![Screen Shot 2023-02-21 at 21.36.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606196/badc73a0-a225-9b36-6ebe-35bd8bd95f5f.png)

- 環境テンプレートから環境名を指定して作成。
- `環境の詳細`の`環境名`は`env_config.json`の記載と合わせる必要がある。
https://github.com/aws-samples/aws-proton-terraform-github-actions-sample/blob/main/env_config.json
- 環境構築の際に選択するRepository nameはgithub actionが含まれるリポジトリを選択。![Screen Shot 2023-02-27 at 18.58.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606196/92075e4d-fe9a-1d1f-677a-ced8ff441616.png)
- 作成を開始するとaws-proton-terraform-github-actions-sampleに対してaws-connector-for-githubからPRが作成される。
- PRが作成される際、環境テンプレートで登録していたterraformのコードと、`proton.auto.tfvars.json`、`proton.service_instance.variables.tf`、`deployment-metadata.json`が作成される。
    - `proton.auto.tfvars.json`：schemaファイルで定義した入力項目が反映され、teraformの変数に渡される。
    - `proton.service_instance.variables.tf`：terraformの変数定義。
    - `deployment-metadata.json`：protonのデプロイバージョンを管理するファイル
- デフォルトのgithub actionではPR作成された際は`terraform plan`までが実行される。
- PRをmergeすることで`terraform apply`が実行され実際の環境が構築される。


### 3. サービステンプレートのうちサービスインスタンスをプロビジョニング
![Screen Shot 2023-02-21 at 21.36.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606196/5191b0be-fed8-4b70-9596-c4ec6a035420.png)

- サービステンプレートからサービス名を指定して作成。
- サービス作成の際はアプリケーションコードが格納されたリポジトリを選択する。
![Screen Shot 2023-02-27 at 20.01.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606196/fc45b6ba-e2aa-815c-9658-638582c49e08.png)
- サービス名、サービスインスタンス名は本来任意の名称で問題ない。
:::note warn
デフォルトのgithub actionのworkflowファイルの分岐に問題があるようで、`サービス名`は`pipeline`にしないと機能しない。ここは後ほど各々でメンテナンスする必要がある。
:::
- サービスインスタンスの構築フローも環境構築時と同様。PR作成時にterraformの変数ファイルが自動作成され、PRが作成される。mergeすることでapplyが実施される。
- protonのサービスとはサービスインスタンスとパイプラインをまとめた名称となっているため、この段階ではパイプラインは構築されずサービスインスタンスのみ作成される。ECSなどもここで構築されるが、nginxのpublicイメージが呼び出されており、welcome画面が表示される状態となる。
- サービスインスタンスの構築が完了すると自動的にproton側からパイプラインの構築がスタートする。



### 4-前半. サービステンプレートのうちパイプラインをプロビジョニング

![Screen Shot 2023-02-21 at 21.37.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606196/e0379b9b-c03d-02df-2947-cf629fc14153.png)

- パイプラインの構築も先述と同様PR作成時にterraformの変数ファイルが自動作成され、PRが作成される。
- コードシリーズの構築の場合、コードパイプラインが作成され、予め選択していたアプリケーションリポジトリからソースを同期する。


### 4-後半. アプリケーションを最終版に更新
- コードシリーズは構築後初回のパイプラインが実行され、コードデプロイの最終処理でprotonのAPIが実行される。そこで具体的なアプリケーションのイメージタグで`proton.service_instance.variables.tf`が更新され再度PRが作成される。
- コードデプロイから呼び出されたproton APIはwait処理を実行するためPRがmerge/applyされるまでinprogressとなる。

### まとめ
AWS proton×terraformを使った環境構築のフローをまとめました。
記載を省略してしまった箇所もあるため随時更新していきたいと思います。

最終的に、自分が管理する環境ではawsのコードシリーズを使わずにgithub action内で完結できる用にworkflowを作成しました。(proton APIを活用して)
次回はgithub actionで作成したworkflowについて記載します。