LayerX エンジニアブログ

LayerX の エンジニアブログです。

LocalStackを用いてローカル開発のシークレット管理をセキュアにする

この記事は、6月から始まっている #LXベッテク月間 33日目の記事です。 前日の記事はtaikyyさんの「LayerXのQAは顧客に届ける価値を最大化したい」でした。

note.com

ちょりす。CTO室およびFintech事業部で色々やってる @ken5scal です。 本日はアプリ開発をローカルで行うためのSecrets管理のTipsを一部、書きたいと思います。

ぱっとアプリを書いて、さくっとコンテナイメージをビルドし、しゅっとAWS上にデリバリしたいことがありませんか? 当社では、そういった場合にAWS App Runnerを活用することがあります。 PoCなど初期段階のものをインフラレイヤーのことを意識したくないときに重宝しています。 しかし、AWSのロードマップにもある通り、ECSでできるようなVauleサービスであるAWS.Secrets Managerとの連携ができません。 とても残念なことです。

External Configuration/Secret Sources · Issue #6 · aws/apprunner-roadmap · GitHub

つまり、アプリ起動時にAWS Secrets Managerを読み込む処理を書かなければなりません。 AWS App Runnerだけでなく、Lambdaもそうですね。

ローカル上からAWS Secrets Managerを読み込みたい場合は、何かしらの方法でローカルにAWSのアクセスキーやセッショントークンを保持しておく必要があります。 開発用のIAM UserのAccess Keyを用意したり、あるいはAWS SSOなどを通して一時的なアクセストークンを取得することが考えられます。 ただ、前者はローテーションが面倒くさいし、後者は有効期限切れに伴う更新が面倒くさいです。 こういった面倒臭さから逃れるには、そもそもローカル開発で実際のAWS Secrets Managerを叩かない方向に進みたいところです。 CTO室やFintech事業部では、localstackのdocker imageを使うことで、ローカル上の疑似AWS Secrets Mangerを構成しています。

  • docker-compose.yml
version: '3'
services:
    image: localstack/localstack:latest
    platform: linux/x86_64
    environment:
      - SERVICES=sqs,s3,dynamodb,lambda,secretsmanager,logs # 使いたいAWSサービスカンマ区切りで設定する
      - DEFAULT_REGION=ap-northeast-1 # リージョンを設定
      - DATA_DIR=/tmp/localstack/data # データ保存するディレクトリ
      - USER=root
    volumes:
      - ~/dev/localstack:/tmp/localstack # ローカルディレクトリをデータ保存ディレクトリへマウント
    ports:
      - 4566:4566 # サービスへのアクセスポートは4566
      - 4567-4584:4567-4584
  • Makefile
serve-local-app: clean-local-db
    @docker-compose up -d
    @sleep 5
    @source local.env \
    && export AWS_ACCESS_KEY_ID=tekito \
            AWS_SECRET_ACCESS_KEY=tekito \
            AWS_SESSION_TOKEN=tekito \
            AWS_DEFAULT_REGION=ap-northeast-1 \
    && aws --endpoint-url=http://localhost:4566 secretsmanager create-secret \
        --name "app/local/AppSecrets" \
        --secret-string '{"CLIENT_SECRET":"'"$${CLIENT_SECRET}"'","SECRET_C": "'"$${SOME_SECRET}"'","BOT_TOKEN": "'"$${BOT_TOKEN}"'"}'
    @export ENV=$(ENV) && air -c air.toml

実際にlocalstack内のsecrets managerに入れたい各種Secretについては、.gitignore対象にした local.env に設定しております。こう書くとlocal.envが危なく聞こえますが、当社はdevとprd環境を完全に分離しています。 それはAWSアカウントだけでなく、普段使うIdPであったりSlackであったりGoogle Workspaceにも開発的思想を持ち込みdev環境を用意しています。これらのサービスは従量課金であるため、そこまでユーザーが増えない開発環境はお財布にも優しく、それ故に導入が容易です。

あまり、こういった開発の裏情報はでてこないので、是非、このブログの読者の中で別の知見を持つ方がいたら教えてください。Twitter DMでもいいですし、下記の通りMeetyもやっております。

meety.net