AWS Copilotの copilot run local を試してみた

# はじめに

先日、AWS Copilotが更新されて、その中にローカルで動かせる`copilot run local`がありましたので、使ってみました。

https://aws.github.io/copilot-cli/blogs/release-v130/#copilot-run-local

# 概要

- `copilot run local`で、デプロイせずにローカルで実行できる
    - ECSで動かした場合に利用可能
    - App Runnerの場合は使えない


# やってみた
## 下準備


まずは`copilot run local`を実行できる状況まで準備するため、前回作った手順を途中まで流用します。Cloud9でやってます。

https://qiita.com/a_b_/items/decf0b0c020cab46e0f8#%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F

copilotコマンドは以下の3つまで進めます。
```
copilot app init
copilot env init
copilot env deploy
```
また、バージョンは1.30以上になっているか確認します。
```
$ copilot -v
copilot version: v1.30.1
```


### ECSで動かす
ここから先は前回と異なり、サービスタイプをECSで動かします。
```
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

  Which Dockerfile would you like to use for frontend?  [Use arrows to move, type to filter, ? for more help]
  > ./Dockerfile
    Enter custom path for your Dockerfile
    Use an existing image instead
```

作成されたマニュフェストファイルは以下です。
```yaml:copilot/frontend/manifest.yml
# The manifest for the "frontend" service.
# Read the full specification for the "Load Balanced Web Service" type at:
#  https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/

# Your service name will be used in naming your resources like log groups, ECS services, etc.
name: frontend
type: Load Balanced Web Service

# Distribute traffic to your service.
http:
  # Requests to this path will be forwarded to your service.
  # To match all requests you can use the "/" path.
  path: '/'
  # You can specify a custom health check path. The default is "/".
  # healthcheck: '/'

# Configuration for your containers and service.
image:
  # Docker build arguments. For additional overrides: https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#image-build
  build: Dockerfile
  # Port exposed through your container to route traffic to it.
  port: 80

cpu: 256       # Number of CPU units for the task.
memory: 512    # Amount of memory in MiB used by the task.
count: 1       # Number of tasks that should be running in your service.
exec: true     # Enable running commands in your container.
network:
  connect: true # Enable Service Connect for intra-environment traffic between services.

# storage:
  # readonly_fs: true       # Limit to read-only access to mounted root filesystems.
 
# Optional fields for more advanced use-cases.
#
#variables:                    # Pass environment variables as key value pairs.
#  LOG_LEVEL: info

#secrets:                      # Pass secrets from AWS Systems Manager (SSM) Parameter Store.
#  GITHUB_TOKEN: GITHUB_TOKEN  # The key is the name of the environment variable, the value is the name of the SSM parameter.

# You can override any of the values defined above by environment.
#environments:
#  test:
#    count: 2               # Number of tasks to run for the "test" environment.
#    deployment:            # The deployment strategy for the "test" environment.
#       rolling: 'recreate' # Stops existing tasks before new ones are started for faster deployments.
```
今回コンテナ化しているアプリでは、'/'では何も戻ってこず、このパスにヘルスチェックをされると困ります。
ヘルスチェックが可能なパスを指定するため、以下のように変更します。

```diff_yaml:copilot/frontend/manifest.yml(一部)
- # healthcheck: '/'
+ healthcheck: '/hello'
```

編集したらデプロイです。
```
copilot svc deploy
```
ヘルスチェックがうまくいかないなど、途中でキャンセルしたい場合はCtrl+Cでデプロイを取り消せます。
6分強ほどでデプロイ完了し、URLがコンソール上に表示されました。

今回のアプリは以下のパスを付けることで実行されるようになっているので、デプロイがうまくいっているのか付与して確かめます。
```
/hello
/hello/jiro/21
/fn?x=2
/plot
```


## `copilot run local`を実行
準備を終えたら、今回追加の以下のコマンドを実行します。
```
copilot run local
```
以下のように、ローカルに立ち上がりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/b99326a4-896b-8524-64e2-180fbed356e5.png)
コマンドを実行したウィンドウはそのままなので、別ウィンドウからアプリを実行します。
```
＄ curl http://0.0.0.0:80/hello

["Hello, world!"]
```

`curl http://127.0.0.1:80/hello`でも呼べました。
他のものも大丈夫そうです。
```
curl http://0.0.0.0:80/hello/jiro/22
curl http://0.0.0.0:80/fn?x=4
curl http://0.0.0.0:80/plot --output pic.png
```

コードを修正した際どうなるのかも見て見ます。まず動いている`copilot run local`をCtrl+Cで停止します。

コードを以下のように変更しました。
```R:sample.R(一部)

#* @get /hello
hw <- function() {
    return("Hello, world!!!!!!!!!!!!!!!!")
}

```
再度、`copilot run local`を実行します。動かせるようになりURLが出てくるまで、ちょっと時間がかかりました。
```
 $ curl http://0.0.0.0:80/hello
["Hello, world!!!!!!!!!!!!!!!!"]
```

デプロイされている方は変更なしでした。確かにローカルだけで変更が確認できる様です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/f412bdc1-c383-488b-9de1-383faa621749.png)

コンテナも新しいものが作られていることが確認できました。新しく作っていたから、時間がかかったものと思われます。
```
 $ docker images
REPOSITORY                                                                             TAG       IMAGE ID       CREATED          SIZE
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-runner-application/frontend   latest    415f12ff60fd   5 minutes ago    1.53GB
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-runner-application/frontend   <none>    9e32856855ae   39 minutes ago   1.53GB
````

# おわりに
今回は新しく追加された`copilot run local`を、簡単ではありますが試してみました。
コンテナのデプロイを良しなにやってくれるAWS Copilotですが、デプロイ前にローカルで実行できるようになり、さらに強力になってきました。
この記事がどなたかのお役に立てれば幸いです。