ECS Fargateに環境変数としてGCPアクセスファイルを渡す

Atrae Advent Calendar 2019 6日目を担当する新卒1年目の小倉です。

昨日は同じく新卒1年目の[土屋の記事](https://qiita.com/tsucchi13/items/faba77f79472e2b03147)でした。

自分は[wevox](https://wevox.io/)という事業でたくましく（？）インフラエンジニアをやっております。

セキュリティ強化からスケーリング、データ基盤の構築など手広くやっております。


wevoxチームでは簡単な定期タスクを、ECS Fargateを使って実行しています。

最近FargateからGCPにアクセスする時の認証で詰まったため、解決方法について書いていきます。

# 全体像

こんな感じです。
肝は環境変数としてCredentialsのJSONファイルを扱い、タスク実行時に渡してやることです。

<img width="924" alt="スクリーンショット 2019-11-30 16.23.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/397863ca-c46f-05c0-1fc7-82b212cd808e.png">

# なぜこうしたか？

## GCPへの認証

GCPの各リソースに外部からアクセスする際は、[Credentialsの認証が必要です](https://cloud.google.com/docs/authentication/production?hl=ja)。
こいつはJSONファイルであり、GCPもファイル形式でしか受け取ってくれません。
そのためただ文字列を渡してもダメで、然るべき内容が含まれた（GCP内で発行するだけですが）JSONにパスを通してやる必要があります。


```
export GOOGLE_APPLICATION_CREDENTIALS="/hoge/fuga/[FILE_NAME].json"
```

## イメージの中にCredentialsを置くこと

今回Secrets ManagerにCredentialsを登録し、run時に環境変数として渡すということをしています。

正直サクッと作るくらいだったらDockerでbuildする時に一緒に固めちゃうのでもいいと思います。
あとGitHubとECRがプライベートだからCredentialsベタ張りでも大丈夫という考えもあります。

しかしやはりCredentialsを一緒にイメージ内に入れてしまうことに気持ち悪さがあります。
本来であれば在処を知っている人を制限するくらいはやってもいいと思います。
つまるところCredentialsベタ張りはセキュリティ上よくないということで、少し時間はかかりましたがこの方法をとりました。



# 手順

- GCP内でCredentialsを発行
- 発行したCredentialsの中身をAWS Secrets Managerに登録
- DockerイメージをECRに登録
- Fargateのタスクを定義


一つずつ確認していきましょう。

## GCP内でCredentialsを発行

GCPのコンソール「APIとサービス」にて「サービスアカウントキー」を作成します。

ここはこれだけなので割愛します。

## 発行したCredentialsの中身をAWS Secrets Managerに登録

AWS上に環境変数となりうる認証情報を登録できるサービスです。

AWSには類似サービスとしてSystem Managerパラメータストアがあります。このサービスとの違いはいくつかありますが、そのうち一つがファイル形式のものを保存できるというものです。

<img width="1187" alt="スクリーンショット 2019-11-30 16.53.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/220617d0-dc99-b608-6686-9620da84aa2b.png">

「+行を追加」と書かれているバーにJSONのキーとバリューを登録していきます。もちろん面倒な時は、JSON形式で書くことも可能です。

<img width="899" alt="スクリーンショット 2019-11-30 16.53.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/d8c34ecf-c893-641a-f036-69fc2fe9a181.png">

あとは登録を進めればOKです。登録が完了すれば、そのキー固有のARN（Amazon Resource Name）が取得できます。


## DockerイメージをECRに登録

イメージを適当に作成してECRにpushしましょう。
ECRにレポジトリを登録し、あとは画面に出てくるコマンドを1つずつ実行すればOKです。

```
$(aws ecr get-login --no-include-email --region ap-northeast-1)

docker build -t hoge/piyo .

docker tag hoge/piyo:latest [ECR repository]/hoge/piyo:latest

docker push [ECR repository]/hoge/piyo:latest
```

## Fargateのタスクを定義

イメージに先ほど登録したECRのURIを貼り付けます。

<img width="1095" alt="スクリーンショット 2019-11-30 17.00.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/35a4d958-2c26-c5b1-ff4c-1b6b8330146a.png">

そしてここがキモになります、というか自分はここで詰まって時間を溶かしました。

<img width="1105" alt="スクリーンショット 2019-11-30 17.08.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/0ac5935d-e269-ffc0-07a4-a2d0e3fa3fbf.png">


やっていることとしては、こんな感じです。

- 環境変数としてKEYを登録。中身は先ほどSecrets Managerに登録したJSONファイルのARN
    - ARNを引っ張ってるので `ValueFrom` にします。
- 環境変数$KEYをechoでリダイレクトし、ファイルを生成（credentials.json）
    - コンテナ内に生成されたファイルにパスを通すので `Value` にします。
- 生成されたファイルをそのままGOOGLE_APPLICATION_CREDENTIALSとして環境変数として登録

こうすることで、Dockerのrun時に一時的にSecrets Managerから呼び出してコンテナの中にファイルを置くことができるわけです。

このGUIですが、Dockerのコマンドにするとこうなります。

```
docker run -e GOOGLE_APPLICATION_CREDENTIALS=credentials.json container_name sh -c `echo $KEY > credentials.json`
```



# 感想

Secrets Manager自体は[有料](https://aws.amazon.com/jp/secrets-manager/pricing/)ですが、Credentialsをそのままレポジトリに登録したり、イメージの中に入れてしまうことを考えたら全然いいと思います。

他にもっと綺麗なやり方ありそうだーと思いつつ、現在の私だとこれがbetterです。

ご意見あればコメントぜひお願いします。マサカリを鬼の勢いで飛ばしてください。

またつい先日、[FargateがEKSで扱えるようになった](https://jp.techcrunch.com/2019/12/05/2019-12-03-aws-announces-eks-on-fargate-is-available/)こともあり、ますますFargate好きが進みそうです。引き続き注目していきます。

# 最後に

ここに自社のブログを貼るのは恐縮ですが、私の働いているチームの[インタビュー記事](https://atrae.co.jp/memberblog/2019/11/27/%ef%bc%83%ef%bc%99/)が先日公開されました！

<img width="486" alt="スクリーンショット-2019-11-19-15.44.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164543/7db7308b-2dff-4a9a-0007-7bd2a67ee352.png">


チームの雰囲気ややっていることもよく分かるので是非ご覧ください。またwevoxやアトラエに興味を持った方、是非ご連絡ください！


明日はyentaチームの遠矢からお送りします！