AWS App Runnerでモテよう 〜PHPシステムアーキテクトを目指して〜

f:id:y3-shimizu:20210521013353p:plain

こんにちは、志水です
先日、ありがたいことに2021 APN ALL AWS Certifications Engineers & AWS Top Engineerに選出されました。周りの皆様の支援があってだと思いますので、本当に感謝しています。

さて、先日は非常にテンションの上がる記事がありましたね。何でしょう?そう、AWS App Runner(以降App Runner)の登場ですね。(AWS Amplify SSR対応も最高でしたね)
もし結婚報道がよぎった方は、本記事を読んで頂きしっかり自分を見つめ直して頂ければと思います。

App Runnerとは

まず簡単にApp Runnerとは何かを説明します。
App Runnerとは、コンテナ環境を簡単にデプロイ出来るフルマネージドなコンピューティングサービスです。
今までコンテナ環境をデプロイする際には、アプリケーションをDockerfileに落とし込んでコンテナ化し、AWSサービスとしてCDKやTerraformなどでVPCやALBからネットワークを作成し、ECSクラスター・サービスを作成し、イメージをECRへプッシュしてデプロイしていました。また、デプロイだけでなく、運用としてCI/CDパイプラインとしてCodePipelineやCodeDeployを設定したり、CloudWatchでメトリクス・ログの監視を行ったり、やる事がいっぱいです。しんどいです
それらをブラックボックス的にまとめてやってくれるのがApp Runnerです。

f:id:y3-shimizu:20210520184607p:plain

App Runnerだとたった最短3ステップでコンテナ環境が出来上がります(すごい!)

  1. ECRのイメージURL or Githubリポジトリ名入力
  2. サービス名入力
  3. ポート番号入力

それ以外の部分はコンソールから自動で作成されたり、ベストプラクティスに沿った設定がデフォルトで指定されていたりします。

また、1で指定するソースをGithub(ソースコード)かECR(コンテナイメージ)かを選択出来るのですが、Githubの場合はランタイムがPython 3かNodejs 12しか選択できない為、それ以外のバージョンor言語であればECRを選択することになります。また、ECRの場合、Dockerfileをビルドする必要があるため、流れは様々ですが基本的にはDockerfile周りを各種リポジトリに格納し、それをビルドしECRにプッシュするという一手間がかかります。

f:id:y3-shimizu:20210520182259p:plain

作ってみる

言語選定

では、早速App Runnerで作っていきましょう。最近はどうやらPHPを使うシステムアーキテクトがモテるらしいので、PHP環境をデプロイしていきましょう。先程の説明より、Python 3でもNodejs 12でもない場合はECRへイメージを上げる必要があるので、今回はECRイメージ作成からやっていきましょう。

コーディング

まずはphpのコードですが、とりあえずサイトに文字を表示するだけの単純なコードにしておきます。

<!--index.php-->
<?php
echo "Hello, PHP on Docker! from hiramasa";
?>

また、折角なので環境情報も見れるようにおなじみphpinfoも出しておきましょう。

<!--hiramasa_room/index.php-->
<?php
phpinfo();
?>

上記のファイルを表示出来るように、Apache入りのPHPのイメージである ‘php:apache’ を利用してみましょう。そして、そのイメージに先程のファイルを入れたDockerfileを作成します。

# Dockerfile
FROM php:apache

COPY ./index.php /var/www/html/
COPY ./hiramasa_room/index.php /var/www/html/hiramasa_room/

ローカルで確認

まずはローカルでこちらのDockerfileをビルドして正常に起動出来ているかを確認してみましょう。

$ docker build -t hiramasa:0.1 .
$ docker run -p 80:80 --name hiramasa -d hiramasa:0.1
$ curl localhost:80
Hello, PHP on Docker! from hiramasa

コンテナを80番ポートで起動し、ローカルの80番ポートを叩くと、index.phpに記載した内容が出力されました。なので、コンテナは正しく起動してそうです。

ECRへプッシュ

では、このイメージをECRにアップしたいのですが、その前にECRのリポジトリを作成しておきましょう。

$ aws ecr create-repository --repository-name hiramasa
{
    "repository": {
        "repositoryUri": "000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/hiramasa", 
...
    }
}

ECRリポジトリが作成されたので、次は先程作成したイメージをプッシュしてみましょう。

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 【AWSアカウントID】.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker tag hiramasa:0.1 【AWSアカウントID】.dkr.ecr.ap-northeast-1.amazonaws.com/hiramasa:0.1
$ docker push 【AWSアカウントID】.dkr.ecr.ap-northeast-1.amazonaws.com/hiramasa:0.1

プッシュされてるかECRリポジトリの中を覗いてみましょう。

$ aws ecr list-images --repository-name hiramasa
{
    "imageIds": [
        {
            "imageTag": "0.1", 
            "imageDigest": "sha256:xxxxx37710f7ad9af73xxxxxa551ff105372b25bee8cb5911e61bfcfcc4xxxxx"
        }
    ]
}

設定したタグが入ってるので問題なさそうです。

App Runnerの設定

ようやくここでApp Runnerが設定できます。ここからは一瞬です。App Runnerのコンソールから「サービスの作成」を選択します。

f:id:y3-shimizu:20210520231300p:plain

サービスのソースは参照を選択して、先程作成したECRとタグを指定すると自動でURIが挿入されます。

f:id:y3-shimizu:20210520231540p:plain

そしてデプロイ設定ですが、ECRがプッシュされる度に自動でデプロイされたいので、トリガーを自動に設定し、ECRへのアクセスを付与するためにサービスロールを作成するようにします。ロール名は自動で入るものでも何でも良いです。そして、次へを選択します。

f:id:y3-shimizu:20210520232026p:plain

最後にサービスの設定になります。サービス名は自分が判別出来れば何でも良いので、今回は「gakki-runner」としておきます。CPUやメモリは今回対して利用しないのでデフォルトのままにします。ちなみに、ここの最大が2vCPUの4GBとなり、あまり大きなアプリケーションは載せれないので注意が必要です。ポートはローカルで起動してたものと同じ80としておきます。ここのポートはコンテナ側のポートになるので、ここで80番を指定したので最終的に出来るサービスがhttpsに出来ない訳ではないです。むしろ全てhttpsで接続出来るようになります。後は次へを選択して確認画面が出るので、作成とデプロイを押すとデプロイされます。

f:id:y3-shimizu:20210520233324p:plain

すると、作成中の画面に遷移するので、4,5分待ちましょう。

その間にアクティビティやログに何が出るのかを眺めてみるのも良いかと思います。アクティビティには現在のステータスが書いてあります。ログはイベントログ・デプロイログ・アプリケーションログの3種類あり、豊富です。また、CloudWatchLogsにも1つのサービスにつき2つのロググループが出来ていて、イベントログ・デプロイログがservice、アプリケーションログがapplicationに当たります。

  • /aws/apprunner/gakki-runner/fba967c76c5e45e7a443b87cf07b158e/service
  • /aws/apprunner/gakki-runner/fba967c76c5e45e7a443b87cf07b158e/application

イベントログはApp Runnerのアクティビティについてのログになり、例えばApp Runner内部でコンテナを起動後に叩いているヘルスチェックがうまくいったかどうかのログが出ます。
次にデプロイログですが、ソースで選択したリポジトリ(今回だとECR)からの取得に関するログが出力されています。IAMロールがおかしいと、ここでエラーが出ます。
最後にアプリケーションログですが、これは名前の通り、作成したアプリケーションのログになります。基本的にコンテナ内部のログで、今回はApacheのログが出ています。

さて、ステータスがRunningになりましたね。失敗時はこの部分がFailになるので、先程説明したログを見てコードを修正していきましょう。

f:id:y3-shimizu:20210521000027p:plain

作成されたサイトを見に行きましょう。画面のデフォルトドメインの部分を選択すると、作成したアプリケーションが見れます

f:id:y3-shimizu:20210521010920p:plain

シンプルなサイトですが、作成した文字が出力されていました。また、phpinfoも見に行きたいので、/hiramasa_room/ に移動します。

f:id:y3-shimizu:20210520190435p:plain

ちゃんとphpinfoが表示されていますね。環境変数を見るとAWS_EXECUTION_ENVにAWS_ECS_FARGATEと入っているので、本当にECS on Fargateで起動してるんだなぁとしみじみします。

注意点

最後にApp Runnerの注意点をお伝えします。

App Runnerの作成は非常に簡単にECSのコンテナ環境がデプロイされますが、リソースはAWS内部に作成されるので、AWSコンソールをいくら探してもECSやVPCが見当たりません。つまり、App Runnerを作成して、細かい部分を調整することは出来ません。
なので、大きなリソースが必要なアプリケーションを利用したい場合や、サイドカー構成のコンテナをデプロイしたい場合など、App Runnerの要件に適合しない場合は利用出来ません。その場合はAWS Copilotでデプロイして細かい部分をCDKやTerraformで調整する形が良いのではないかなと思います。
ちなみに、同日発表されたAmplify SSR対応はAmplifyからデプロイするとCloudFrontやLambda@Edgeのリソースが見れるので、各種修正が出来る自由度があります。

また、phpのコードのhiramasaの部分をyusukeに変更、プッシュして自動デプロイが走るかを見ようとしましたが、動きませんでした。設定が足りないのかもしれませんが、おそらくhiramasaの修正は控えるようにという事かと思いますので、ご注意下さい。

まとめ

App RunnerでPHPを動かせれば自然とモテるので、みなさんガンガンApp Runner触ってガンガン要望上げていきましょう!

f:id:y3-shimizu:20210330181533j:plain

執筆者志水友輔

2021 APN ALL AWS Certifications Engineers & AWS Top Engineer
大阪でAWSを中心としたクラウドの導入、設計、構築を専門に行っています。