はじめに
少し前に作っていたplumberのコンテナを、今回はAWS Copilot CLIを使って動かしてみました。
AWS Copilotはサービスのタイプがいくつかありますが、今回は以下の記事を参考にApp Runnerで動かします。
やってみた
Cloud9(t3.small)でやってみました。
IAM の設定
専用のIAMユーザーを作ります。権限は指定がなかったためAdministratorAccess
を付与しました。
touch createCopilotUser.yaml
AWSTemplateFormatVersion: "2010-09-09"
Resources:
UserDefine:
Type: AWS::IAM::User
Properties:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess
aws cloudformation create-stack --stack-name createCopilotUser \
--template-body file://createCopilotUser.yaml \
--capabilities CAPABILITY_NAMED_IAM
またCloud9で、認証にtempporary credentialsを使わないように、OFFにします。
あとはそれを公式にあるようにaws configure
で指定します。
$ aws configure
AWS Access Key ID [None]: <アクセスキーID>
AWS Secret Access Key [None]: <シークレットアクセスキー>
Default region name [None]: <使用するリージョン>
Default output format [None]: json
$ aws sts get-caller-identity
{
"Account": <アカウントID>,
"UserId": <ユーザーID>,
"Arn": "arn:aws:iam::<アカウントID>:user/copilot-user"
}
AWS Copilot のインストール
Linuxなので、以下のコマンドでインストールしました。
curl -Lo copilot https://github.com/aws/copilot-cli/releases/latest/download/copilot-linux && chmod +x copilot && sudo mv copilot /usr/local/bin/copilot && copilot --help
デプロイするアプリのクローン
こちらは自作のPlumberのアプリを使います。以前の記事を参考に、ディレクトリとファイル作成を行います。
AWS Copilot Application を初期化する
初期化コマンドです。
copilot app init
以下の問いが出てきますので、公式にあるように答えていきました。
What would you like to name your application? [? for help] my-app-runner-application
ここでcopilot init
と打つと、ApplicationとServiceを一緒に作ることになります。
公式と同様、CFnスタックや、パラメータストアが作られていました。
またファイルもつくられていましたので、tree風のコマンドでチェックします。
$ pwd;find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/| /g'
/home/ec2-user/environment/test-plumber
|--copilot
| |--.workspace
|--Dockerfile
|--plumber.R
|--sample.R
中身は先ほど指定したアプリケーション名が入っているだけでした。
application: my-app-runner-application
AWS Copilot Environment を作成する
以下で環境を作ります。
copilot env init
以下のように問われるので、公式にあるように答えていきます。
What is your environment's name? [? for help] dev
Which credentials would you like to use to create dev? [Use arrows to move, type to filter, ? for more help]
Enter temporary credentials
> [profile default]
Would you like to use the default configuration for a new environment?
- A new VPC with 2 AZs, 2 public subnets and 2 private subnets
- A new ECS Cluster
- New IAM Roles to manage services and jobs in your environment
[Use arrows to move, type to filter]
> Yes, use default.
Yes, but I'd like configure the default resources (CIDR ranges, AZs).
No, I'd like to import existing resources (VPC, subnets).
5分程度で終わりました。
作られたマニュフェストファイルの中身は以下のようになっていました。
クリックで表示
# The manifest for the "dev" environment.
# Read the full specification for the "Environment" type at:
# https://aws.github.io/copilot-cli/docs/manifest/environment/
# Your environment name will be used in naming your resources like VPC, cluster, etc.
name: dev
type: Environment
# Import your own VPC and subnets or configure how they should be created.
# network:
# vpc:
# id:
# Configure the load balancers in your environment, once created.
# http:
# public:
# private:
# Configure observability for your environment resources.
observability:
container_insights: false
次に環境のデプロイです。
copilot env deploy
複数あれば--name xxx
で指定するようですが、今回は一つだけなので未指定で動きます。
特に入力は求められず、色々なリソースがつくられます。
Request-Driven Web Service の作成
Serviceを作ります。
copilot svc init
入力内容は公式に従いました。
Which service type best represents your service's architecture? [Use arrows to move, type to filter, ? for more help]
> Request-Driven Web Service (App Runner)
Load Balanced Web Service (Internet to ECS on Fargate)
Backend Service (ECS on Fargate)
Worker Service (Events to SQS to ECS on Fargate)
Static Site (Internet to CDN to S3 bucket)
What do you want to name this service? [? for help] frontend
Would you like to accept traffic from your environment or the internet? [Use arrows to move, type to filter, ? for more help]
Environment
> Internet
Which Dockerfile would you like to use for sampleplumber? [Use arrows to move, type to filter, ? for more help]
> ./Dockerfile
Enter custom path for your Dockerfile
Use an existing image instead
作られたマニュフェストファイルは以下になります。色々なことが設定できそうですが、デフォルトだと最低限になっているようです。
クリックで表示
# The manifest for the "frontend" service.
# Read the full specification for the "Request-Driven Web Service" type at:
# https://aws.github.io/copilot-cli/docs/manifest/rd-web-service/
# Your service name will be used in naming your resources like log groups, App Runner services, etc.
name: frontend
# The "architecture" of the service you're running.
type: Request-Driven Web Service
image:
# Docker build arguments.
# For additional overrides: https://aws.github.io/copilot-cli/docs/manifest/rd-web-service/#image-build
build: Dockerfile
# Port exposed through your container to route traffic to it.
port: 80
# http:
# healthcheck:
# path: /
# healthy_threshold: 3
# unhealthy_threshold: 5
# interval: 10s
# timeout: 5s
# Number of CPU units for the task.
cpu: 1024
# Amount of memory in MiB used by the task.
memory: 2048
# Connect your App Runner service to your environment's VPC.
# network:
# vpc:
# placement: private
# Enable tracing for the service.
# observability:
# tracing: awsxray
# Optional fields for more advanced use-cases.
#
# variables: # Pass environment variables as key value pairs.
# LOG_LEVEL: info
#
# tags: # Pass tags as key value pairs.
# project: project-name
#
# secrets: # Pass secrets from AWS Systems Manager (SSM) Parameter Store and Secrets Manager.
# GITHUB_TOKEN: GITHUB_TOKEN # The key is the name of the environment variable, the value is the name of an SSM parameter.
# You can override any of the values defined above by environment.
# environments:
# test:
# variables:
# LOG_LEVEL: debug # Log level for the "test" environment.
これをデプロイします。
copilot svc deploy
こちらも複数あれば--name xxxx
で指定しますが、1つだけなので未指定で実行します。
途中の画面ですが、メッセージが赤く出てくるので、少々心臓に悪いです。
6分ほど待ち、結果にURLがでてきました
Recommended follow-up action:
- You can access your service at https://xxxxxxxxx.ap-northeast-1.awsapprunner.com over the internet.
WAFを付ける
以前App Runnerを作ったときはWAFを付けて作成しました。
Copilotでもできるようなのでやってみます。
参考
ファイル作成
以下のディレクトリとファイルを追加します。
mkdir copilot/frontend/addons
touch copilot/frontend/addons/waf.yml
touch copilot/frontend/addons/addons.parameters.yml
WAFを作って、先のApp Runnerに紐づけます。WAFはIP許可リストとしています。
CFnがそのまま使えます。
#Addon template to add WAF configuration to your App Runner service.
Parameters:
App:
Type: String
Description: Your application's name.
Env:
Type: String
Description: The environment name your service, job, or workflow is being deployed to.
Name:
Type: String
Description: The name of the service, job, or workflow being deployed.
ServiceARN:
Type: String
Default: ""
Description: The ARN of the service being deployed.
AllowAddresses:
Type: CommaDelimitedList
Default: "1.1.1.1/32,2.2.2.2/32"
Resources:
WAFIPSet:
Type: AWS::WAFv2::IPSet
Properties:
Name: IPAllowLists
Scope: REGIONAL
IPAddressVersion: IPV4
Addresses: !Ref AllowAddresses
WebACL:
Type: AWS::WAFv2::WebACL
Properties:
Name: WebACL_AppRunner
Scope: REGIONAL
DefaultAction:
Block: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: WebACL_AppRunner
Rules:
-
Name: rules-allow-ip
Priority: 0
Action:
Allow: {}
Statement:
IPSetReferenceStatement:
Arn: !GetAtt WAFIPSet.Arn
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: rules-allow-ip
Firewall:
Metadata:
'aws:copilot:description': 'Associating your App Runner service with your WAF WebACL'
Type: AWS::WAFv2::WebACLAssociation
Properties:
ResourceArn: !Sub ${ServiceARN}
WebACLArn: !GetAtt WebACL.Arn
パラメータは以下のファイルで指定しますが、最初はIPは指定せず/waf.yml
のデフォルトがセットされるかを見てみます。
Parameters:
ServiceARN: !Ref Service
# AllowAddresses: ""
デプロイ
デプロイします。先ほどと同じコマンドで、変更にも対応してくれます。
copilot svc deploy
ちゃんとWAFが作成されました。
デフォルトの値でIP許可リストが作成されました。URLにアクセスしても、見れないことが確認できます。
パラメータを指定してみます。確認くんなどで、自分のIPアドレスを指定します。
Parameters:
ServiceARN: !Ref Service
- # AllowAddresses: ""
+ AllowAddresses: "自分のIPアドレス/32"
copilot svc deploy
片付け
copilot app delete
で、S3バケットも消してくれます。Cloud9内のファイルは.workspace
ファイルは消されますが、他ファイルは残ったままでした。
Are you sure you want to delete application testcopilot? [? for help] (Y/n) Y
最初にIAMユーザを作ったCFnスタックも、必要に応じて削除してください。
おわりに
今回はAWS Copilot CLIでApp Runnerを試してみました。
以前CFnで作成した時とは異なり、ECRを用意することなく、対話式でよしなに作成できたので、大変楽に作れました。
この記事がどなたかのお役に立てれば幸いです。