57
67

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS ECSでRDSにアクセスするアプリを動かすことはじめ

Last updated at Posted at 2019-03-21

tl;dr

図のように、AWS初心者がECSコンテナ上にRDBをRead/WriteするWebアプリを動かすまでの手順です。

TODO:

  • 自作WebアプリのDockerイメージをFargateタスクとして起動させた
  • WebアプリからRDSへのアクセス方法
  • System ManagerのSecureStringを環境変数にとりコンテナからRDSにアクセス方法

前置き

Sinatra

未経験からRuby on Railsを学んで仕事につなげるまでの1000時間メニュー をやっています。
未経験ではないので記載どおりの時間はかけていませんが自学するのにバランスがよいと思っています。
学習の過程でDBアクセスの伴うSinatraアプリケーションを作りました。

URL: https://github.com/yysaki/sinatra-workout-recording

AWS

また並行してAWSについて手を動かしてます。
普段触らないモダンな環境がどんなものか知りたいというのがモチベーションです。
1月ごろから手を動かしていましたようです:

今回Sinatraアプリの一環でこれのDockerイメージを作ったので、AWSのコンテナ上で動かしてみたくなりました。
Amazon EKSが東京リージョンに対応した 話もありますが、ハマりどころが多そうなのでまずは手始めにECSから。

実際に手を動かしてみると、

  • RDBとECSが接続するためファイアウォールをどう設定するか
  • 秘密情報であるDBの接続情報をどうコンテナに渡すか

などが疑問になり、解決できたので書きます。

AWSの下準備

これら本題ではありませんが、自分の理解度の確認のため書きます。

AWSアカウントの初期設定

最初の IAM 管理者のユーザーおよびグループの作成 - AWS Identity and Access Management
アカウントを作成したらこの記事に従ってやります。
ルートユーザーを使わずにAdministrator用アカウントを使用するのが記事中でベストプラクティスとされているので、セキュリティステータスを埋めておきます:

スクリーンショット 2019-03-21 19.07.24.png

まだある程度手を動かしてからこの記事に気づきました。
AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ - Qiita
大変参考になりますのでおいおい追従していきたいです。

AWS CLIのインストール

ECRのpushに使うのでAWS CLIをインストールしておきます。
AWS CLI のインストールと設定 - Amazon Kinesis Data Streams

以下のようにCLIのインストール、初期設定をします。

pip install awscli
aws configure

リージョンはap-northeast-1を指定します
成功すれば ~/.aws/ 配下にconifgおよびcredentialsが保存されます。

ECSのチュートリアルをやっておく

Fargate を使用した Amazon ECS の使用開始 - Amazon Elastic Container Service
この手順で一度サービスを稼働させて、Fargateのクラスターや ecsTaskExecutionRole IAMロールを用意しておきます。

ECRにDockerイメージを仕込む

Amazon ECR における Docker の基本 - Amazon ECR
これはCLIで簡単に作業が完結できました。
「(オプション) イメージの Amazon Elastic Container Registry へのプッシュ」を参考にリポジトリへpushします:

$(aws ecr get-login --no-include-email)
aws ecr create-repository --repository-name sinatra-workout-recording
docker pull yysaki/sinatra-workout-recording
docker tag yysaki/sinatra-workout-recording {aws_account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/sinatra-workout-recording
docker push {aws_account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/sinatra-workout-recording

ECSタスクを起動してRDSに接続させる

ここからが本題です。

まずRDSを立てる

MySQL DB インスタンスを作成して MySQL DB インスタンス上のデータベースに接続する - Amazon Relational Database Service
この手順の通り進めてMySQLインスタンスを作成します。
このとき、「開発/テスト - MySQL」のユースケースを選び、「RDS 無料利用枠の対象オプションのみを有効化」をチェックして作成すれば無料枠で済みます。

RDSにアクセスできるようにする

通常はファイアウォールによりRDSに直接アクセスすることはできません。
そこで、「VPCセキュリティグループ」から図のようにローカルIPのCIDRを指定することでローカルからも接続できるようになります。

スクリーンショット 2019-03-21 17.25.54.png

環境変数の保持

DBアカウント情報は秘匿すべき情報なので、ソースコードに記載せず環境変数で取り扱うやりかたを計画しました。
今回のsinatraのアプリではactiverecordを使いますが、環境変数DB_URLでRDSへの接続文字列を渡すことにします。

ActiveRecord::Base.establish_connection(ENV['DB_URL'])

書式は mysql2://{DBユーザ名}:{DBパスワード}@{エンドポイント}/{DB名} で、一つの環境変数で設定できるので便利でした。

ECSにサービスを作成する前にECSコンテナにDBアクセスの情報を安全に渡す仕組みが必要なのですが、以下の記事がためになりました。

【祝!】FargateでもECSにごっつ簡単に環境変数に機密情報を渡せるようになりました!
AWS Systems ManagerのパラメータストアにSecureStringとして保持し、これをECSタスクから読み出す仕組みです。
ごくごく最近導入された機能のようで手間が少なくて助かります。

図のように設定を行います:

スクリーンショット 2019-03-21 19.10.43.png

公式ドキュメントとしてはこれです:
機密データの指定 - Amazon Elastic Container Service

環境変数を設定したECSタスクを立てる

ECSのタスク定義を行います。
先程のSecureStringを読めるよう、以下のjsonによる「ユーザによる管理」タイプのポリシーを定義し、 ecsTaskExecutionRole ロールに付与します:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssm:GetParameters",
        "secretsmanager:GetSecretValue",
        "kms:Decrypt"
      ],
      "Resource": "*"
    }
  ]
}

また、タスク定義を作成する際、「コンテナの定義」 > 「コンテナの編集」 > 「環境」の環境変数に対して図のように設定します。

スクリーンショット 2019-03-18 20.35.58.png

その他は先の「ECSのチュートリアルをやっておく」の要領でECSタスク定義して、サービスを稼働させればよいです。

コンテナからRDSに接続できるようにして動作確認

VPCセキュリティグループの設定を行ってRDSに接続できるようにします。

  • ECSタスクがアクティブになったら「詳細」タブにある「Public IP」を見て、RDSのVPCセキュリティグループのインバウンドのルールに追記する
    • ただしIPアドレスは可変なので、安定稼働させるうえで改善の余地が大いにあると感じます

以上で設定が完了しタスクが稼働していますので「Public IP」にブラウザからアクセスすることでアプリの動作が確認できました。
ECS -> RDSへの接続については課題を感じるので、どう自動化するかは今後の課題として調べていきたいとお思います。

なお料金

RDBは無料枠がありますが、ECSでは起動タスクに対する課金を避けられない認識です。
しかしFargate起動タスクはvCPUを細かく刻めるので、お試しに安く使えて便利でした。
0.5GB 0.25vCPUのFargateを稼働させた課金額のslack通知の様子です:

スクリーンショット 2019-03-21 17.59.09.png

初めの1.08$はRoute53のドメイン管理で、残りがECSのぶんです。
丸一日稼働させても0.41$程度で済みました。

57
67
1

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
57
67

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?