🙌

App Runnerを使ってSpringBootのコンテナ環境を爆速で用意する

2022/09/30に公開

SREホールディングス株式会社 でサーバーサイド兼インフラエンジニアをやっている釜田です。

弊社では、インフラ環境でECS、FargateといったAWSのコンテナサービスを利用しているのですが、インフラ経験のないサーバーサイドエンジニアの方にとって、CI/CDを含めたコンテナ環境の構築は少しハードルが高いです。
そこで今回は、コンテナイメージを用意するだけでAWS上にCI/CDを含めたコンテナ環境を用意してくれるAWSのマネージドサービスApp Runnerについて紹介します。

対象読者

  • CI/CDを含めたコンテナ環境を構築するハードルを高く感じている方
  • コンテナ環境でのアプリ開発に注力したい方

課題

  • AWS上にCI/CDを含めたコンテナ環境の構築は、アプリ開発者にとってハードルが高い
    (VPC、Auto Scaling、ALB、ECS、Fargate、CodeBuildなど利用するサービスが多い)
  • インフラ担当者にお願いすると開発までのリードタイムが発生してしまう

App Runnerとは?

  • コンテナイメージを用意するだけでAWS上でコンテナ化されたWebアプリケーションを
    動かせるサービス
  • 利用者から見えるのはAppRunnerだけ(コンテナ環境を構成するサービス群であるVPC,ECS,Fargate等のリソースはAppRunnerとして抽象化されているため、確認できません)

  • ユーザーの責任範囲はApplicationのみ

https://twitter.com/toricls/status/1413341668342865921

  • 内部的にはECS+Fargateで動いています

できること

  • 自動デプロイ
    ECRに新しいイメージをPushした際にアプリケーションが自動デプロイされます。
    (デプロイ方式はBlue/Greenデプロイ)
  • オートスケール
    設定した同時リクエスト数の閾値を基準にしてAuto Scalingでスケールアウト、スケールインできます。
  • ログとメトリクス
    CloudWatch Logsにイベントログ、デプロイログ、アプリケーションログのロググループが自動で作成されます。
    Request count,Request latencyなどのメトリクスが取得できます。
  • 環境変数
    コンテナで利用する環境変数を設定できます。
  • カスタムドメイン
    任意のドメインを設定可能です。
  • VPC内のPrivateなリソースへのアクセス
    「VPC Connector」を利用することでVPC内のRDSなどのプライベートリソースにアクセス可能です。

できないこと

  • IP制限
    WAFを直接アタッチできないのでIP制限をかけたり、Webアプリケーションに対する攻撃を防いだりできません。
    そのため、AppRunnerにデプロイされたサービスはパブリックで公開されます。
    WAF連携はAppRunnerのロードマップに上がっているので今後に期待ですね。
    https://github.com/aws/apprunner-roadmap/issues/58
  • 複数イメージを利用した構成
    AppRunnerは単一のコンテナイメージを使ったWebアプリケーションをデプロイするサービスなので
    ECSタスクのように複数のコンテナイメージを組み合わせる構成はできません。
  • 認証情報を安全に渡せない
    Secret Managerと連携できないので認証情報を安全にコンテナに渡せません。

実際にSpringBootアプリケーションをデプロイしてみる

構成図

流れ

  • SpringBootのアプリケーションを作成
  • Push先のECRリポジトリを作成
  • ローカルでDockerイメージ作成&ECRにPush
  • AWSコンソール上でApp Runner作成
  • デプロイされているか確認
  • 再度新しいイメージをPushして自動デプロイされて更新されることを確認

SpringBootのアプリケーションを作成

"Hello World!"をレスポンスするだけのアプリケーションを作成します。

AppRunnerDemoApplication.java
@SpringBootApplication
@RestController
public class AppRunnerDemoApplication {

	@RequestMapping("/")
	public String home() {
		return "Hello World!";
	}

	public static void main(String[] args) {
		SpringApplication.run(AppRunnerDemoApplication.class, args);
	}
}

ECRのリポジトリを作成

$ AWS_REGION=ap-northeast-1
$ aws ecr create-repository --repository-name apprunner-demo --region ${AWS_REGION}

ローカルでDockerイメージ作成&ECRにPush

ローカルでイメージをbuildして、ECRにpushします。

Dockerfile
FROM amazoncorretto:17
COPY build/libs/\*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
$ docker build -t apprunner-demo . --platform amd64 
$ ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`
$ AWS_REGION=ap-northeast-1
$ docker tag apprunner-demo:latest ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/apprunner-demo:latest
$ docker push ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/apprunner-demo:latest

AWSコンソール上でApp Runner作成

AWSコンソールを開いて、AppRunnerのサービスページでApp Runnerサービスを作成を押下します。

ソース及びデプロイの設定
  • コンテナイメージのURLの右にある参照を使って先ほどPushしたイメージを選択します
  • 自動デプロイを試したいので自動を選択します
  • ECRにPushするためのサービスロールを作成したいので新しいサービスロールの作成を選択します
    上記設定後、次へを押下します。

サービスの設定

サービス名を適当に入力して、その他はデフォルトで次へを押下します。

確認

作成とデプロイを押下します。

デプロイ確認

サービスのステータスがRunningに、App Runnerへのデプロイに成功しています。
デフォルトドメインのURLにアクセスすると、Hello World! と返るのが確認できます。

$ curl https://xxxxxxxxxx.ap-northeast-1.awsapprunner.com/
Hello World!

Pushした最新のイメージが自動デプロイされるか確認

以下のようにレスポンスの文字列をHello AppRunner!! に書き換えて、イメージを作成して、
再度ECRにpushします。

AppRunnerDemoApplication.java
@RequestMapping("/")
public String home() {
	return "Hello App Runner!!";
}

AWSコンソール上で自動デプロイが走ることが確認できます。

再度curlでリクエストを投げるとpushした新しいイメージでデプロイされたことが確認できました。

$ curl https://xxxxxxxxxx.ap-northeast-1.awsapprunner.com/
Hello App Runner!!

最後に

App Runnerの特徴とSpirngBootアプリケーションをデプロイする際の適用例を紹介しました。
GCPのCloud Runと比べるとIP制限ができないなど劣っている部分もありますが、
ロードマップもあるのでApp Runnerの今後の機能追加に期待ですね。

参考

SRE Holdings 株式会社

Discussion