話題のAWS App RunnerをPython3 × Flaskで試してみる

https://www.youtube.com/watch?v=HJsULvSJWes

## 概要

つい先日AWSから発表されたApp Runnerを試してみたのでメモ書き。

巷では「GCPの[Cloud Run](https://cloud.google.com/run)に似た感じのもの」と言われているみたいですが、僕はそちらのサービスを使った事がないため、今回はなかなか新鮮でした。

実際の体験やドキュメント読んだ上でざっくり説明するなら、

<font color="Red">アプリのソースコードを渡すだけで簡単にデプロイ可能かつ、面倒なインフラ設定（ネットワーク、オートスケーリング、ロードバランシング、SSL、CI/CDなど）は全てAWS側が勝手にやってくれるサービス</font>

といった感じでしょうか。（違ったらごめんなさい...。イメージ的にはLambdaに似てるかも）

通常、何かアプリをデプロイしようと思ったら諸々の手順を踏む必要があったりしますが、App Runnerを使う場合、

- GitHubと連携してソースコードをインポート
- ちょっとした設定（CPU・メモリ、コンテナ起動後のコマンドなど）を記述

本当に簡単な操作だけで何とかなっちゃいます。

![app-deploy-lifecycle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/bb42554b-db34-a978-e761-c56840a30b3c.png)

参照記事: [What is AWS App Runner?](https://docs.aws.amazon.com/apprunner/latest/dg/what-is-apprunner.html)


ごちゃごちゃ説明するよりも手を動かした方がわかりやすいと思うので、少しでも興味があればこの先を読んでみてください。

## 仕様

- Python3
- Flask
- AWS App Runner
- Docker

※ローカルでの環境構築はDockerで行います。

## 実装

アプリ作成編とデプロイ編の2本立てになります。

### アプリ作成

まず最初に、Python3 × Flaskで簡単なアプリを作成しましょう。

#### 各種ディレクトリ & ファイルを作成

```
$ mkdir python3-flask-docker-sample && cd python3-flask-docker-sample
$ touch Dockerfile
$ touch docker-compose.yml
$ touch requirements.txt
$ touch app.py
```

```dockerfile:./Dockerfile
FROM python:3.9-alpine

ADD . /code
WORKDIR /code

RUN pip install --upgrade pip
RUN pip install -r requirements.txt
```

```yml:./docker-compose.yml
version: "3"
services:
  flask:
    container_name: flask
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
    command: flask run --host 0.0.0.0 --port 5000
```

```:./requirements.txt
flask
```

```py:./app.py
from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello World!"

@app.route("/api/v1/hello")
def hello():
    return jsonify({
        "message": "Hello World!"
    })

if __name__ == "__main__":
    app.run()
```

#### 動作確認

```
$ docker-compose up -d
```

![スクリーンショット 2021-05-23 3.10.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/c2fdf3d6-4d88-140b-884c-15bad2edd7ab.png)

[localhost:5000](http://localhost:5000/) にアクセスして「Hello World!」が返ってくれば成功です。

もしくは

```
$ curl http://localhost:5000/api/v1/hello

{
  "message": "Hello World!"
}
```

curlコマンドで確認してもOK。

https://github.com/kazama1209/python3-flask-docker-sample

一応、完成品のコードを載せておくので、もし万が一動かない場合などがあれば比較してどこか間違っていないか確認してください。

```
$ git add .
$ git commit -m 'Initial commit'
```

正常な動作確認ができたら、GitHubに適当なリポジトリを作ってプッシュしておいてください。（後ほどApp Runnerにデプロイする際、GitHubからソースコードを読み込む事になるのでこの作業は必須です。）

### デプロイ 

アプリの準備ができたのでいよいよデプロイです。と言っても、驚くほど簡単に出来てしまうので拍子抜けしてしまうかもしれません。

![スクリーンショット 2021-05-23 3.20.40_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/9e79b414-e630-2791-4f6a-7673e7813793.jpeg)


AWSコンソール画面から「App Runner」を探し出し、「サービスを作成」をクリック。

![スクリーンショット 2021-05-22 18.27.42_censored (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/57cdb6c4-b892-4d94-5bb5-1c1ee1786900.jpeg)

リポジトリタイプは「ソースコードリポジトリ」を選び、GitGubとの接続を行うために「新規追加」をクリック。

![スクリーンショット 2021-05-22 18.28.29_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/0b4d6c4a-ddc5-1331-c759-ebde65924a26.jpeg)

接続名を適当に入力し、「別のアプリケーションをインストールする」をクリック。

![スクリーンショット 2021-05-22 18.28.40_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/5e5e9e31-8802-05c8-525e-9cfcf15cc528.jpeg)

どのGitHubアカウントにコネクターをインストールするか選択。

![スクリーンショット 2021-05-22 18.29.06_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/acc61127-f697-4dda-99c6-a4b69bfecaeb.jpeg)

「All repositories（全てのリポジトリ）」を対象にするか、「Onle select repositories（選択したリポジトリ一つだけ）」を対象にするか聞かれますが、今回は「All repositories」にします。（将来的に新しいリポジトリが追加された場合にそちらも対象となるので便利そう。）

![スクリーンショット 2021-05-22 18.29.27_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/c3be80b1-7f0d-9b42-03f9-cff2176a8b7a.jpeg)

接続に成功すると、先ほどは空欄だった「GitHubアプリケーション」の欄にGitHubアカウント名が追加されるので、このまま「次へ」をクリック。

![スクリーンショット 2021-05-23 3.40.41_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/45a53e53-46eb-50f4-810a-b89f80c300f2.jpeg)


- リポジトリ
  - 事前にプッシュしておいたリポジトリ
- ブランチ
  - master（人によっては「main」など）
- デプロイ設定
  - お好み（「自動」にしておくと、今後masterブランチに変更があった場合は勝手にデプロイが行われるようになるので楽かも）

![スクリーンショット 2021-05-23 3.52.47_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/97dc1a03-b7f1-d5d1-3743-0d1c2fb657e7.jpeg)

- 設定ファイル
  - ここですべての設定を構成する
- Python3
- 構築コマンド
  - pip install --upgrade pip && pip install -r requirements.txt
- 開始コマンド
  - flask run --host 0.0.0.0 --port 5000
- ポート
  - 5000

ちなみに、今回はコンソール画面から設定を行なっていますが、リポジトリ内に「apprunner.yaml」というファイルを配置しておくと、そちらから設定を読み込んでくれるみたいです。

たとえば、今回であれば以下のような感じになりますね。

```yaml:./apprunner.yaml
version: 1.0
runtime: python3
build:
 commands:
  build:
  - pip install --upgrade pip
  - pip install -r requirements.txt
run:
 command: flask run --host 0.0.0.0 --port 5000
 network:
   port: 5000
```

参照記事: [Introducing AWS App Runner](https://aws.amazon.com/jp/blogs/containers/introducing-aws-app-runner/)

![スクリーンショット 2021-05-23 3.59.46_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/7ae5965e-442f-1b24-b96d-362fc5cf8ff2.jpeg)

- サービス名
  - 任意
- その他
  - 今回は全てデフォルトでOK

本格的な運用を行う際は色々とパラメータをいじくる必要がありそうですが、今回はただのサンプルなので基本はデフォルトで大丈夫です。もしこだわりなどがあればお好みで。

![スクリーンショット 2021-05-23 4.03.01_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/99780c11-5634-1a2f-b693-4e86a220fed6.jpeg)

最後に諸々の確認画面が出てくるので、問題無さそうなら一番下にある「作成とデプロイ」をクリック。

![スクリーンショット 2021-05-23 4.04.29_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/ecf686ce-e2ed-1675-d08b-5c2e7d4a7ccc.jpeg)

するとこんな感じでデプロイが始まるので、完了するまで少し待ちましょう。大体５分前後で終わると思います。

![スクリーンショット 2021-05-23 4.09.57_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/dc9bacaf-cd5a-4146-5cd6-d6c4edd13b4f.jpeg)

無事成功したら、表示されているドメインにアクセスしてみます。

![スクリーンショット 2021-05-23 4.11.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/5709f1cb-fcec-5719-7cf2-cd77d0a7cfaf.png)

ちゃんとデプロイできてますね。

```
$ curl https://pj2qck2byp.ap-northeast-1.awsapprunner.com/api/v1/hello

{
  "message": "Hello World!"
}
```

curlコマンドでの確認もバッチリです。

![スクリーンショット 2021-05-23 5.11.54_censored.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/b8d93c81-f688-2676-b2ee-dac54513ea2a.jpeg)

もし困ったことがあれば、CloudWatchのログに吐き出されているはずなので適宜デバッグしてください。

## あとがき

いかがだったでしょうか。あまりにも簡単にデプロイできる事がお分かりいただけたと思います。

本来であれば、ちょっとしたアプリであっても「ネットワークを準備して〜、ロードバランサーを作って〜、オートスケーリングの設定をして〜、SSL証明書を発行して〜、CI/CD環境を構築して〜」」みたいな諸々の作業が必要になったりするものですが、App Runnerであればその辺を全く意識せずによしなにやってくれるぽいので、開発者としては非常に楽な思いができそうです。

まだまだ新しいサービスなので、僕もまだその全てを活かし切れてない感は否めませんが、今後ぼちぼち試してみたいなと。

なお、今現在はPython3とNode.jsにしか対応していなさそうな感じですが、ソースをGitHubリポジトリではなくECRを選択した場合は他の言語でもいけるぽいです。（SNSなどではPHPを使ったアプリをデプロイしている方をお見かけしました。）

多くの要望があれば対応言語も増えていくでしょうし、今後に期待。

自分も何か面白い事ができないか模索していきたいところです。