Dockerコンテナ上のアプリにSecrets Manager経由でDBの接続情報を設定する
前回、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"をクリック。
"Credentials for RDS database"を選択し、
Auroraのシークレット情報(ユーザ名とパスワード)を入力します。
"Select which RDS database this secret will access"で、
作成したAuroraのインスタンスを選択します。
次のページでは、シークレット名とDescriptionを入力します。
シークレット名には「/」が使えますので、階層型の名前を定義できます。
シークレット情報のローテーションの設定ができますが、
今回はデフォルトのDisableのままとします。
シークレットが作成されると、前掲の手順で入力したユーザ名、パスワードの他に、
DBエンジン名、RDSエンドポイント、ポート番号、DB識別子が
自動保存されます。
シークレットを取得するためのコードスニペットも確認可能です。
コンテナをビルドする環境を準備
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のチュートリアルでいい感じのイメージが紹介されていました。
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を新規作成します。
#!/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を追記します。
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に変更、
などを行います。
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)
動作確認
アプリにアクセスしてみましょう。
起動しましたね。
Register!をクリックして、ゲスト情報を登録してみます。
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 | [email protected] | 3
(1 row)
コンテナが起動時にSecrets ManagerからDB接続情報を取得し、
アプリの処理によってAuroraにデータが保存できたことが確認できました。
ECS/Fargateでも動きます
Dockerイメージはできましたので、
ECRにPushし、ECSのクラスタとタスク定義、サービスを作成すれば、
ECS上でも同様に動かすことができます。
Dockerアプリケーションのセキュリティレベル向上の参考になれば幸いです。
Author And Source
この問題について(Dockerコンテナ上のアプリにSecrets Manager経由でDBの接続情報を設定する), 我々は、より多くの情報をここで見つけました https://qiita.com/tomoya_oka/items/29c84b599dd7e1750f1f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .