AWSを使ったLINE BOTの開発（おまけで簡易CIも）

# はじめに

- LINE BOTを作成し、実行環境にHerokuを使って使用していた。
- 業務でAWSを使い始めたこともあり、実行環境をHerokuからAWSに移してみた。
- ここでは、備忘録も兼ねて、移行の際に行った一部手順についてまとめた。
- LINE BOTの作成方法や、AWSについては知っていることを前提とする。

# 構成図

- 今回のシステムの構成図は以下の通り。

![ORION.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/6694d1d1-e6f9-e33f-f95b-2dfcde977874.png)

- 以下の2箇所の構築方法について、次章以降でまとめていく。

![ORION3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/9a066905-0f6a-10d1-8158-f8d25188e07e.png)

# HTTPS化

- 構成図でいうとこの部分。
- EC2上で実行しているLINE BOT実行環境（Nginxコンテナ＋Flaskコンテナ）へのHTTPS通信のために、**ELB**をEC2の前に置くことでHTTPS化を行った。
- ドメイン作成、Route53によるドメイン登録は済んでいるものとして進める。

![ORION1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/5dd2d3ca-b074-1aac-373e-90cd250f7ce6.png)

## セキュリティーグループの作成

- EC2とELBのセキュリティーグループを作成し、各自に割り当てる。

### ELB

- ELBがAWS外からの通信の受け口となるため、インバウンドルールに以下を追加してセキュリティーグループを作成する。
- 外からの通信はHTTPS通信のため、ポートは443とする。

![sg-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/3c078631-76fa-fbcb-368b-0e067b3cf4b9.png)

### EC2

- ELB→がEC2へのアクセスのため、インバウンドルールに以下を追加してセキュリティーグループを作成する。
- ELBとEC2間はHTTP通信のため、ポートは80とする。
- ELBのセキュリティーグループをソースに指定することで、対象のELB以外の通信は拒否することとなり、セキュリティーが高まる。

![sg-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/28ba8a37-d5f8-3514-0aa4-28846edcd425.png)

## SSL証明書の発行

- AWS Certificate Managerを使用して証明書を発行。
- 作成手順については以下のサイトを参照。   
https://recipe.kc-cloud.jp/archives/11084


## ELBの作成

- ELBは3種類のロードバランサーをサポートしていて、今回はHTTPS通信を行うアプリケーションのため「ALB」を使用。
- 作成手順については以下のサイトを参照。  
https://dev.classmethod.jp/articles/alb-backend-https/

### ポイント
- 今回はHTTP通信にしたいので、リスナーは「HTTPS」「443」にすること。

![elb1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/3dd8bc2b-e3ec-7e10-07c4-1c7938610007.png)

- ELBからEC2へはHTTP通信でかわまないので、ターゲットグループは「HTTP」「80」にすること。

![elb5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/ed344e47-ef89-e603-417a-040613339e37.png)

## Route 53でドメイン名とELBとの関連付け

- ELB作成後は、Route 53でドメイン名とELBの関連付けを行う。

### 手順

- 該当のホストゾーンの「レコードの作成」から「シンプルルーティング」を選択。

![route1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/93e89e66-4408-b381-2494-c30b2121c643.png)

- 作成したELBを選択。

![route2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/7ff47fee-3991-fc07-999a-5c63411c05b7.png)

- Aレコードが作成される。

![route3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/4c96e6eb-993b-12d8-0123-d4d7ccf2e35f.png)

# Dockerイメージのビルドと格納

- 構成図でいうとこの部分。
- 簡易CI/CDを構成してみた。
- LINE BOTを動かすのに必要ではないが、実行環境のEC2でDockerコンテナを使用しているので、そのDockerイメージのために設定を行った。

![ORION2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/2c534f08-eee5-0c8d-6fa9-4603ac00cbfc.png)

## 構成手順

### ECRでリポジトリの作成

- 作成手順については以下のサイトを参照（基本的にはDockerイメージ格納用のリポジトリを作成するだけ）  
https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html

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

- 設定方法については以下のサイトを参照。  
https://dev.classmethod.jp/articles/20170225-codebuild-docker/
- ソースプロパイダ（Dockerfileなどのソースを格納するプロバイダ）はGitHub。
- 以下、ソースプロパイダの種類によるビルド実行について（2種類しか検証できていないです・・・）

|ソースプロパイダ|挙動|
|---|---|
|GitHub|Webhookの設定が可能で、「push→CodeBuild起動→ビルドの実行」が可能|
|CodeCommit|「push→CodeBuild起動→ビルドの実行」を行うにはCodePiplineが必要|

- ビルドを実行するための仕様や設定を書いたbuildspec.ymlを作成する必要があり、書き方のサンプルは以下を参照。

```yml:buildspec.yml
version: 0.2

phases:
  install:
    runtime-versions:
      docker: 18
  pre_build:
    commands:
      - echo $IMAGE_REPO_NAME
      - echo $IMAGE_TAG
      - echo $AWS_ACCOUNT_ID
      - echo $AWS_DEFAULT_REGION
      - echo Logging in to Amazon ECR...
      - $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)

  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG

  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
```

## 実際のCIの流れ

- DockerイメージがECRに格納されるまでの大まかな流れは以下の通り。
    - Github上のリポジトリへpush（Dockerfile＋buildspec.yml）
    - Code Buildによるビルドの実行
    - 成功するとECRにDockerイメージを格納