俺、このAWS Amplify Consoleでコンテナの自動デプロイ環境が出来たら結婚するんだ

この記事は[AWS Amplify Advent Calendar 2019](https://qiita.com/advent-calendar/2019/aws-amplify)の11日目です。
今回はAWS Amplify Consoleを使ったAWS Fargateのデプロイをご紹介します。

### tl;dr
* amplify addから利用出来るカテゴリだけでなく好きなカテゴリを自由に作成できます。
* AWS Amplify ConsoleではCloudFormationテンプレートをデプロイすることが出来るため高度なカスタマイズが可能です。
* フロントエンドなしでバックエンドのみのデプロイがAWS Amplify Consoleから可能です。

### 利用するライブラリのバージョン
ライブラリ|version|
:--|:--|
node|v12.13.0|
@aws-amplify/cli|4.2.0|

では早速やってみましょう！

### 今回作るもの
下記の通り、GitHubにCloudFormationテンプレートをpushすることでAWS Amplify Consoleが自動的にFargateリソースをデプロイする環境の構築をご紹介します。

<img width="712" alt="DynamoDB設計検討.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/b86da29a-76ff-408d-d117-6a6db63c3664.png">


### 初期構築
`amplify init` コマンドでAmplifyプロジェクトの初期化を行います。
今回は`environment: local` としています。これは後で使うので忘れないようにしましょう。
Amplify Cliの詳しい使い方は[こちら](https://aws-amplify.github.io/docs/cli-toolchain/quickstart)をご覧ください！ 
![スクリーンショット 2019-12-07 23.22.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/aea2cc23-4acc-3d32-22b6-67ae7edbddf6.png)

### 確認
`amplify status`コマンドでローカルとクラウドのデプロイ状況の差分をチェックすることが出来ます。
![スクリーンショット 2019-12-07 23.24.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/0ae22382-f1a2-f903-1510-a4536ba484d7.png)

### 現在のディレクトリ構成
![スクリーンショット 2019-12-07 23.26.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/f3eb6c94-15f7-9e7d-92ac-4b35307a93ce.png)


### backend-config.jsonの編集
初期値は空のjsonになっています。`backend-config.json`のフォーマットは以下の通りです。

```json:backend-configのフォーマット
{
  "<custom-category-name>": {
    "<custom-resource-name>": {
      "service": "<custom-aws-service-name>",
      "providerPlugin": "awscloudformation"
}
```

今回は以下のように書き換えました。

```json:amplify/backend/backend-config.json
{
  "fargate": {
    "adventCalendar2019": {
      "service": "ECS",
      "providerPlugin": "awscloudformation"
    }
  }
}
```

### backend-config.jsonに合わせて以下の場所にCloudFormationテンプレートを配置します
ファイル形式はjson or yamlですが今回はyamlで書きます。
詳しくは[こちら](https://aws-amplify.github.io/docs/cli-toolchain/quickstart#custom-cloudformation-stacks)を参照下さい。
![スクリーンショット 2019-12-07 23.40.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/53e34316-f2e0-32bf-cdeb-c7250612c5e2.png)


いきなりFargateまで書くのは大変なのでまずはVPCとサブネット1つだけデプロイしてみましょう！

```yaml:amplify/backend/fargate/adventCalendar2019/template.yaml
---
AWSTemplateFormatVersion: "2010-09-09"
Description: "AWS Amplify Advent Calendar 2019"
Parameters:
  env:
    Type: "String"
    Description: "The environment name. e.g. Dev, Test, or Production"
    Default: "NONE"
Resources:
  AdventCalendar2019Vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub "AdventCalendar2019Vpc-${env}"
  AdventCalendar2019VpcPublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.0.0/18
      VpcId:
        Ref: AdventCalendar2019Vpc
      AvailabilityZone:
        Fn::Select:
          - 0
          - Fn::GetAZs: ""
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub "AdventCalendar2019VpcPublicSubnet1-${env}"
```

amplifyは`env`という変数名にenvironment名を入れてCloudFormationを実行してくれます。
今回の例だと`local`というenvがインジェクションされます。

### 注意！！
ここで`amplify status`コマンドを打ってもFargateカテゴリが出てきません。
![スクリーンショット 2019-12-07 23.45.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/5ff201b3-547a-1675-4187-5f0a9379976d.png)

[公式ドキュメント](https://aws-amplify.github.io/docs/cli-toolchain/quickstart#custom-cloudformation-stacks)に従って以下のコマンドを打ちます。
`amplify env checkout <current-env-name>`
今回の環境名は `local` のため `amplify env checkout local` と打ちます
![スクリーンショット 2019-12-07 23.46.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/2a5b02bf-71f2-bdbb-268b-89a9ebc3c849.png)

### 確認
Fargateカテゴリが認識できました！
![スクリーンショット 2019-12-07 23.46.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/af4fd4ff-886d-1a6c-e94f-904b8c140196.png)



### デプロイ
`amplify push`コマンドでクラウド上にデプロイ出来ます。（処理のログが長いのでバッサリ切っています）
![スクリーンショット 2019-12-07 23.55.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/6d8da875-509d-772a-3b2d-6cb8e6bef091.png)


### Amplify Console
`amplify console`コマンドでブラウザからデプロイした対象を確認することが出来ます
![スクリーンショット 2019-12-07 23.57.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/65283865-d589-60bf-2342-b2427b88c84b.png)


### GitHubのmasterブランチにpushされたら自動的にデプロイする設定
まずはGitHub認証を選択しましょう
![スクリーンショット 2019-12-07 23.59.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/6f9a44e5-934f-ea69-9677-fba5cc489399.png)

そして認証してリポジトリとブランチを選択します
![スクリーンショット 2019-12-08 0.01.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/cb954d3e-724c-312c-ac8e-61852eb0c19a.png)

ビルドの設定を確認しましょう。今回選択しているIAMロールはバックエンドのデプロイをするために強い権限を持たせています。
[こちら](https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/how-to-service-role-amplify-console.html)と全く同じ設定をしたロールで実行しています。
`amplify.yml` をリポジトリの一番上の階層に配置することでビルドのコマンドなど変更が可能ですが、今回はこのまま実行します。
![スクリーンショット 2019-12-08 0.38.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/7b385b8d-54bd-07c1-17e0-116828adc0cb.png)

3分ほど待ったらビルドが完了しました。
![スクリーンショット 2019-12-08 0.41.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/621508e1-f27a-7d20-685d-50a6150f8bd3.png)

これで自動デプロイの設定が出来たはずですのでもう一つサブネットを追加してGitHubにpushしてみます。

```yaml:amplify/backend/fargate/adventCalendar2019/template.yaml
---
AWSTemplateFormatVersion: "2010-09-09"
Description: "AWS Amplify Advent Calendar 2019"
Parameters:
  env:
    Type: "String"
    Description: "The environment name. e.g. Dev, Test, or Production"
    Default: "NONE"
Resources:
  AdventCalendar2019Vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: !Sub "AdventCalendar2019Vpc-${env}"
  AdventCalendar2019VpcPublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.0.0/18
      VpcId:
        Ref: AdventCalendar2019Vpc
      AvailabilityZone:
        Fn::Select:
          - 0
          - Fn::GetAZs: ""
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub "AdventCalendar2019VpcPublicSubnet1-${env}"
  AdventCalendar2019VpcPublicSubnet1RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId:
        Ref: AdventCalendar2019Vpc
  AdventCalendar2019VpcPublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId:
        Ref: AdventCalendar2019VpcPublicSubnet1RouteTable
      SubnetId:
        Ref: AdventCalendar2019VpcPublicSubnet1
  AdventCalendar2019VpcPublicSubnet1DefaultRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId:
        Ref: AdventCalendar2019VpcPublicSubnet1RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId:
        Ref: AdventCalendar2019VpcIGW
    DependsOn:
      - AdventCalendar2019VpcGW
  AdventCalendar2019VpcIGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "AdventCalendar2019VpcIGW-${env}"
  AdventCalendar2019VpcGW:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId:
        Ref: AdventCalendar2019Vpc
      InternetGatewayId:
        Ref: AdventCalendar2019VpcIGW
```

無事にビルドが通ってデプロイ出来ました（ビルド2はSyntaxエラーで失敗したので省略してますｗ）
![スクリーンショット 2019-12-08 1.19.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/513414db-76d1-579c-9690-a60be7e69237.png)


### Fargateリソースの作成
Fargate作成に必要なCloudFormationテンプレートに更新し、GitHubにPushします。
長くなるため最終的なテンプレートは[こちら](https://github.com/yuukiyo/amplify-blog-sample/blob/master/amplify/backend/fargate/adventCalendar2019/template.yaml)をご確認下さい。

無事にビルドが完了し、ECSのページからデプロイされているリソースが確認できました！
![スクリーンショット 2019-12-09 0.48.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155341/b482b991-36c8-36aa-f646-8ae237c6eb41.png)


### まとめ
いかがでしたか？
AWSのCI/CDツールチェーンはCodePipelineやCodeBuildなどが事例で見かけることが多いと思います。
AWS Amplify Consoleがこんなに手軽に自動デプロイ環境を作れることはあまり知られていないのではないでしょうか？

ということで今回はフロントエンドなしでFargateのみの自動デプロイ機能を紹介しました。

AWS Amplify Console/Cli/Frameworkには他にも様々な便利な機能がありますので是非[AWS Amplify Advent Calendar2019](https://qiita.com/advent-calendar/2019/aws-amplify)で記事を探してみてください！
それではまたお会いしましょう！