Amazon Web Services ブログ

ECSタスクのためのIAMロールによってコンテナ利用アプリケーションをより安全にする

Amazon ECSでは、コンテナから簡単にAPIリクエストを行うために、Amazon EC2のIAMロールをいつでも使うことができます。これによって、AWSの認証情報をコードや設定ファイルに保存しないというAWSのベストプラクティスに従うことができる上に。鍵の自動ローテーションといった利点も得られます。

例えば、ECSとAmazon S3を使った秘匿情報管理システムを作ったり、Amazon DynamoDBを使って状態管理したり、S3を使ってコンテナによって生成された成果物を保存したり、ということがロールによって可能であり、全てにおいてAWSの認証情報をコードの中に全く持つ必要がありません。

今までは、Amazon EC2のIAMロールを使う必要がありました。つまり、ECSクラスタのEC2インスタンスに紐付いたIAMポリシーは同一クラスタ内で実行されるタスクが必要な全てのIAMポリシーを含んでいる必要がありました。これは、もし1つのコンテナが特定のS3バケットへのアクセスが必要で、他のコンテナがDynamoDBテーブルへのアクセスが必要であった時、同一のEC2インスタンスに両方のIAM権限を与える必要があることを意味しています。

新しく公開されたECSタスクのためのIAMロールの導入によって、EC2コンテナインスタンスではなくECSタスクに直接IAMロールを紐付けることで、基盤をより安全に保つことができます。この手法によって、1つのタスクはS3にアクセスする特定のIAMロールを使いながら他のタスクはDynamoDBテーブルへにアクセスするIAMロールを使うことができます。

この機能によって、ECSクラスタインスタンスのIAMポリシーも最小限にすることが可能です。なぜなら、ECSサービスとやり取りするために必要な2,3のIAM権限を与えるだけで良いからです。

この記事で、タスクIAMロールのセットアップを眺めてみましょう。

必要条件

もしまだであればECSクラスタを作成し、最低でも1つのEC2インスタンスをクラスタ内に起動します。EC2インスタンスを起動するとき、Container instance IAM roleとして、AmazonEC2ContainerServiceforEC2RoleポリシーがアタッチされたIAMロールを選択します。

もし既存のクラスタがあれば、ECS最適AMIの2016.03.eを使い、この機能を使うために2016年7月13日リリースかそれより新しいSDKを使います。

デモンストレーション

このデモでは、Amazon S3バケットを作成し’Hello World’ファイルをアップロードするだけの簡単なNode.jsアプリケーションを使います。アプリケーションのソースコードはaws-nodejs-sampleのGitHubレポジトリにあります。

Dockerイメージをビルドしプッシュする

ターミナルアプリケーションで、以下のコマンドを実行します:

$ git clone https://github.com/awslabs/aws-nodejs-sample

すると現在のディレクトリの下にaws-nodejs-sampleという名前のディレクトリが作られ、サンプルアプリのコードが配置されます。そのディレクトリでDockerfileというファイルを作成し、以下のテキストを貼り付け保存します。

FROM node:argon

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY sample.js /usr/src/app

CMD [ "node", "sample.js" ]

イメージを保存するためにAmazon ECRにaws-nodejs-sampleという名前のレポジトリを作成します。以下のコマンドを実行してDockerイメージをビルドしECRレポジトリにプッシュします。AWSリージョンとアカウントIDを適切なものに置換してから実行して下さい。

$ docker build -t aws-nodejs-sample .

$ aws ecr get-login --region us-west-2 | sh

$ docker tag aws-nodejs-sample:latest 123456789012.dkr.ecr.us-west-2.amazonaws.com/aws-nodejs-sample:v1

$ docker push 123456789012.dkr.ecr.us-west-2.amazonaws.com/aws-nodejs-sample:v1

タスクのためのIAMロールを作成する

タスクのためのIAMロールを作成しますAWS Service Rolesとして、Amazon EC2 Container Service Task Roleを選択し、Attach Policy画面ではAmazonS3FullAccessというIAM管理ポリシーを選択します。

タスク定義を作成し、タスクを起動

サンプルアプリのためのタスク定義を作成しますConfigure via JSONを選択してJSONビルダーに切替え、以下のテキストをAWSリージョンとアカウントIDを適切な値に置換しながら貼り付けます。

{
    "containerDefinitions": [
        {
            "name": "sample-app",
            "image": "123456789012.dkr.ecr.us-west-2.amazonaws.com/aws-nodejs-sample:v1",
            "memory": 200,
            "cpu": 10,
            "essential": true,
            "portMappings": []      
        }
    ],
    "volumes": [],
    "family": "aws-nodejs-sample"
}

Task Roleには、先ほど作成したIAMロールを選択し、Createを選択してタスク定義を作成します。

Task Definitionのページで、今作成したaws-nodejs-sample:1のような名前のリビジョンを選択し、ActionsからRun Taskを選択します。リストからECSクラスタを選択し、次の画面でRun Taskを選択してECSクラスタ上にタスクを起動します。

Amazon S3コンソールを開いてバケットが作成されhello_world.txtというファイルが含まれていることを確認します。バケットの名前はnode-sdk-sample-UUIDという形式になっています。

注意: 予期せぬ課金を避けるためには、上記の例で作成された、S3バケットを空にしてから削除しEC2インスタンスを削除しておきます。

まとめ

以上の例でお分かりのように、IAMの使い方やタスクには必要最低限の権限だけを与えるというAWSベストプラクティスに従うのが簡単になっています。それによって、他のタスクがアクセスできることを意図していないデータにアクセスしてしまうリスクを最小化することができます。

これはさらにECSクラスタ管理も簡潔にしてくれ、同じクラスタインスタンス上にタスクを同居させるための自由をもっと高めてくれます。注意点としてセキュリティグループは依然としてインスタンス単位で管理する必要がありますが、IAMポリシーの作成や紐付けについてはきめ細かく行うことができます。

タスクIAMロールの詳細はECSドキュメントをご覧下さい。質問や意見がございましたら、以下のコメント欄をご利用下さい。

原文: Help Secure Container-Enabled Applications with IAM Roles for ECS Tasks (翻訳: SA岩永)