LoginSignup
10
11

More than 5 years have passed since last update.

Dockerコンテナ上のアプリにSecrets Manager経由でDBの接続情報を設定する

Posted at

前回、Parameter StoreとSecrets Managerの機能比較を行いました。

AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか?比較 - Qiita

パラメータストアに一度に大量アクセスするとThrottlingExceptionが発生する件は、
別途検証して見極めたいと思います。

ECSでは、Task Definition中の環境変数にDBのユーザ名、パスワードを含めることは推奨されていません。
今回は、Secrets ManagerからDB接続に必要なユーザ名やパスワード等を取得し、
コンテナの環境変数に設定する方法を検証してみます。

データストアを作成する

RDSであればなんでもいいのですが、
今回はSecrets Managerで標準サポートされているAurora PostgreSQL-CompatibleでDBを作成します。

作成方法はクラメソさんのブログを参考にさせて頂きましょう。

PostgreSQL 互換 Amazon Auroraが正式リリースされました | Developers.IO

Secrets ManagerにDB接続情報を保存する

Secrets Managerにアクセスします。
"Store a secret"をクリック。
sm_000001.JPG

"Credentials for RDS database"を選択し、
Auroraのシークレット情報(ユーザ名とパスワード)を入力します。

sm_000002.JPG

"Select which RDS database this secret will access"で、
作成したAuroraのインスタンスを選択します。
sm_000003.JPG

次のページでは、シークレット名とDescriptionを入力します。
シークレット名には「/」が使えますので、階層型の名前を定義できます。
sm_000004.JPG

シークレット情報のローテーションの設定ができますが、
今回はデフォルトのDisableのままとします。
sm_000005.JPG

Reviewで内容を確認し、シークレットを作成します。
sm_000006.JPG

シークレットが作成されました。
sm_000008.JPG

シークレットが作成されると、前掲の手順で入力したユーザ名、パスワードの他に、
DBエンジン名、RDSエンドポイント、ポート番号、DB識別子が
自動保存されます。
sm_000009.JPG

シークレットを取得するためのコードスニペットも確認可能です。
sm_000007.JPG

コンテナをビルドする環境を準備

IAMロールを利用すれば、AWS各種サービスへのアクセス制御が簡単且つセキュアに実現できます。
よって、今回はコンテナをビルドする環境にはAmazon Linuxを使います。

IAMロールを作成

EC2を起動する前にIAMロールを作成しておきます。

サービスの選択では"EC2"を選択し、
名前は"Ec2InstanceRoleForECS"とでもしておきましょう。

ポリシーは、AWS Managed Policyから

  • AmazonEC2ContainerServiceforEC2Role
  • SecretsManagerReadWrite

をAttachします。

EC2を起動

EC2を起動します。今回は、
Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type - ami-06cd52961ce9f0d85
を利用しました。

起動の手順は割愛しますが、以下にご注意下さい。

  • シークレットを保存したSecrets Managerと同じリージョンを利用する。
  • 前掲の手順で作成したIAMロールをアタッチする。
  • DockerイメージをPullする必要があるため、EC2からインターネットにアクセス可能にしておく。
  • セキュリティグループでポート22と80へのインバウンドアクセスを許可する。(アクセス元は絞りましょう)
  • (忘れがち注意)前掲の手順で作成したAurora(PostreSQL)のセキュリティグループにて、本EC2のセキュリティグループ(or サブネット)からのポート5432へのインバウンドアクセスを許可する。

Dockerの環境をセットアップ

EC2にec2-userでログインし、dockerとgitをインストールします。

$ sudo yum -y install docker
$ sudo yum -y install git

dockerとgitがインストールされたことを確認。

$ docker --version
Docker version 18.03.1-ce, build 3dfb8343b139d6342acfd9975d7f1068b5b1c3d3
$ git --version
git version 2.14.4

ec2-userをdockerグループに追加。

sudo usermod -a -G docker ec2-user

dockerを起動。

$ sudo service docker start
Starting cgconfig service:                                 [  OK  ]
Starting docker:        .                                  [  OK  ]

さて、Aurora(PostgreSQL)に接続するほどよい感じのDockerイメージを探していたのですが、
AzureのWeb App for Containersのチュートリアルでいい感じのイメージが紹介されていました。

GitHub - Azure-Samples/docker-flask-postgres: A Flask application that demonstrates how to build data-driven Python apps in Azure App Service.

flaskを使っているのは趣味ですのあまり気にしないで下さい。
AzureやAWSの違いを意識せず、イメージをpullして利用できるところがDockerの素晴らしいところです。

Githubからリソースをクローンします。

$ git clone https://github.com/Azure-Samples/docker-flask-postgres.git

ディレクトリが作成されるので移動。

$ cd docker-flask-postgres
$ ls
app  Dockerfile  LICENSE  README.md  requirements.txt

設定ファイル修正

README.mdによると

docker build -t docker-flask-sample .
docker run -it --env DBPASS="" --env DBHOST="" --env DBUSER="" --env DBNAME="" -p 5000:5000 docker-flask-sample

でアプリが実行できます。

が、Secrets ManagerからDB接続情報を取得したいのと、
アプリのポートを80に変更したいので、各種設定ファイルを修正します。

コンテナ起動時にENTRYPOINTを活用してDB接続情報をSecrets Managerから取得⇒環境変数に設定したいので、
entrypoint.shを新規作成します。

entrypoint.sh
#!/bin/bash

set -e

export SECRET=$(aws --region ap-northeast-1 secretsmanager get-secret-value --secret-id dev/docker-flask-postgres/postgres | jq .SecretString | jq fromjson)

export DBUSER=$(echo $SECRET | jq -r .username)
export DBPASS=$(echo $SECRET | jq -r .password)
export DBNAME=$(echo $SECRET | jq -r .dbClusterIdentifier)
export DBHOST=$(echo $SECRET | jq -r .host)

exec "$@"

パーミッションも変更しておきましょう。

$ chmod +x entrypoint.sh

コンテナにAWS CLIが必要になりますので、
requirements.txtの最終行にawscliを追記します。

requirements.txt
alembic==0.9.1
appdirs==1.4.3
click==6.7
Flask==0.12.1
Flask-Migrate==2.0.3
Flask-Script==2.0.5
Flask-SQLAlchemy==2.2
itsdangerous==0.24
Jinja2==2.9.6
Mako==1.0.6
MarkupSafe==1.0
packaging==16.8
psycopg2==2.7.1
pyparsing==2.2.0
python-editor==1.0.3
six==1.10.0
SQLAlchemy==1.1.9
Werkzeug==0.12.1
+ awscli==1.15.71

最後に、Dockerfileを修正します。
ENTRYPOINTの設定、jqのインストール、flaskのリッスンポートを80に変更、
などを行います。

Dockerfile
FROM tiangolo/uwsgi-nginx-flask:python3.6

COPY requirements.txt /
+COPY entrypoint.sh /

WORKDIR /

+RUN pip install --upgrade pip && \
+    pip install -r ./requirements.txt --no-cache-dir
-RUN pip install -r ./requirements.txt --no-cache-dir
+RUN apt-get -y update && \
+    apt-get -y install jq
+ENTRYPOINT ["/entrypoint.sh"]

COPY app/ /app/

WORKDIR /app

ENV FLASK_APP=app.py
-CMD flask db upgrade && flask run -h 0.0.0.0 -p 5000
+CMD flask db upgrade && flask run -h 0.0.0.0 -p 80

Dockerイメージをビルドして起動

では、ビルドしてみましょう。

$ docker build -t flask-postgresql-sample .

コンテナを起動。

$ docker run -it -p 80:80 flask-postgresql-sample
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
 * Serving Flask app "app"
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

動作確認

アプリにアクセスしてみましょう。

app_20180826_01.JPG

起動しましたね。
Register!をクリックして、ゲスト情報を登録してみます。

app_20180826_02.JPG

登録できました。
app_20180826_03.JPG

DBを確認してみる

Auroraの方を確認してみます。

pythondb=> \dt;
              List of relations
 Schema |      Name       | Type  |  Owner
--------+-----------------+-------+----------
 public | alembic_version | table | pythondb
 public | guests          | table | pythondb
(2 rows)

pythondb=> select * from guests;
 id |   name   |       email        | partysize
----+----------+--------------------+-----------
  1 | hogehoge | hogehoge@qiita.com |         3
(1 row)

コンテナが起動時にSecrets ManagerからDB接続情報を取得し、
アプリの処理によってAuroraにデータが保存できたことが確認できました。

ECS/Fargateでも動きます

Dockerイメージはできましたので、
ECRにPushし、ECSのクラスタとタスク定義、サービスを作成すれば、
ECS上でも同様に動かすことができます。

Dockerアプリケーションのセキュリティレベル向上の参考になれば幸いです。

10
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
11