Amazon ECS タスクの IAM ロール
Amazon ECS タスクには IAM ロールを関連付けることができます。IAM ロールで付与される許可は、タスクで実行されているコンテナによって引き受けられます。このロールにより、(コンテナ上の) アプリケーションコードが他の AWS サービスを使用できるようになります。タスクロールは、アプリケーションが Amazon S3 などの他の AWS サービスにアクセスするときに必要です。Amazon ECS がコンテナイメージをプルしてタスクを実行するために必要な IAM 許可については、「Amazon ECS タスク実行IAM ロール」を参照してください。
タスクロールを使用する利点は次のとおりです。
-
認証情報の分離: コンテナは、コンテナが属するタスク定義で定義された IAM ロールの認証情報のみを取得できます。コンテナは、別のタスクに属する別のコンテナを対象にした認証情報にアクセスすることはありません。
-
認可: 認可されていないコンテナは、他のタスク用に定義された IAM ロール認証情報にアクセスできません。
-
監査: CloudTrail にアクセスしイベントのログ記録を利用することで、遡及的な監査を確実に行えます。タスクの認証情報には、セッションにアタッチされている
taskArn
のコンテキストがあるため、CloudTrail ログではどのタスクがどのロールを使用しているかを表示できます。
注記
タスク用の IAM ロールを指定すると、そのタスクのコンテナ内の AWS CLI または他の SDK は、タスクロールによって提供された AWS 認証情報を排他的に使用し、Amazon EC2 または外部インスタンスで実行されていて、それらから IAM 許可を継承しなくなります。
タスクの IAM ロールを作成する
タスクで使用する IAM ポリシーを作成するときは、そのポリシーはタスクのコンテナが引き受けるタスクの許可を含める必要があります。既存の AWS マネージドポリシーを使用することも、特定のニーズを満たすカスタムポリシーを最初から作成することもできます。詳細については、『IAM ユーザーガイド』の「IAM ポリシーの作成」を参照してください。
重要
Amazon ECS タスク (すべての起動タイプ) では、タスクに IAM ポリシーとロールを使用することをお勧めします。これらの認証情報により、タスクは sts:AssumeRole
を呼び出してタスクに既に関連付けられているのと同じロールを引き受けることなく、AWS API リクエストを行うことができます。タスクでロールがそれ自体を引き受けることが必要な場合、そのロールがそれ自体を引き受けることを明示的に許可する信頼ポリシーを作成する必要があります。詳細については、「IAM ユーザーガイド」の「ロール信頼ポリシーの更新」を参照してください。
IAM ポリシーを作成した後、Amazon ECS タスク定義で参照するポリシーを含む IAM ロールを作成できます。IAM コンソールで [Elastic Container Service Task] (Elastic Container Service タスク) ユースケースを使用してロールを作成できます。その後、タスクのコンテナに必要なアクセス許可を付与するロールに特定の IAM ポリシーをアタッチできます。次の手順では、これを行う方法について説明します。
IAM のアクセス許可を必要とする複数のタスク定義またはサービスがある場合は、各タスクに提供するアクセスを最小限に抑えるために、タスクを操作するために必要な最小限のアクセス許可で特定のタスク定義またはサービスごとにロールを作成することを検討してください。
リージョンのサービスエンドポイントの詳細については、Amazon Web Services 全般のリファレンス ガイドの「サービスエンドポイント」を参照してください。
IAM タスクロールは、ecs-tasks.amazonaws.com
サービスを特定する信頼ポリシーが必要です。sts:AssumeRole
許可は、Amazon EC2 インスタンスが使用するロールとは異なる IAM ロールをタスクに引き受けられるようにします。これにより、タスクは Amazon EC2 インスタンスに関連付けられたロールを継承しません。以下に示しているのは、信頼ポリシーの例です。リージョン識別子を置き換えて、タスク起動時に使用する AWS アカウント番号を特定します。
{ "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Principal":{ "Service":[ "ecs-tasks.amazonaws.com" ] }, "Action":"sts:AssumeRole", "Condition":{ "ArnLike":{ "aws:SourceArn":"arn:aws:ecs:
us-west-2
:111122223333
:*" }, "StringEquals":{ "aws:SourceAccount":"111122223333
" } } } ] }
重要
タスク IAM ロールを作成するときは、信頼関係またはロールに関連付けられた IAM ポリシーで aws:SourceAccount
または aws:SourceArn
のいずれかの条件キーを使用してアクセス許可のスコープを詳細にし、複雑な副セキュリティ問題を防止します。特定のクラスターを指定する aws:SourceArn
条件キーの使用は現在サポートされていません。ワイルドカードを使用してすべてのクラスターを指定する必要があります。混乱した代理の問題と、お客様の AWS アカウントの保護方法の詳細について学ぶためには、[The confused deputy problem] (IAM ユーザーガイド) の[IAM User Guide] (混乱した代理の問題) を参照してください。
以下の手順では、Amazon S3 からオブジェクトを取得するポリシーを作成する方法を、ポリシー例とともに説明します。すべてのユーザー入力
を自分の値に置き換えてください。
以下の手順では、作成した IAM ポリシーをアタッチすることでタスクの IAM ロール を作成する方法を示しています。
ロールを作成したら、次の機能のアクセス許可をロールに追加します。
機能 | 追加のアクセス許可 |
---|---|
ECS Exec を使用する |
|
EC2 インスタンスを使用する (Windows および Linux) | |
外部インスタンスを使用する | |
EC2 Windows インスタンスを使用する |
ECS Exec のアクセス許可
ECS Exec 機能には、マネージド型 SSM エージェント (execute-command
エージェント) と SSM サービス間の通信に必要なアクセス許可をコンテナに付与するためのタスク IAM ロールが必要です。次のアクセス許可をタスク IAM ロールに追加し、タスク定義にタスク IAM ロールを含める必要があります。詳細については、IAM ユーザーガイドのIAM ポリシーの追加と削除を参照してください。
タスク IAM ロールに次のポリシーを使用して、必要な SSM アクセス許可を追加します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel" ], "Resource": "*" } ] }
Amazon EC2 インスタンスの追加設定
コンテナインスタンスのロールの許可は、以下に提供されるマネージド型 AmazonEC2ContainerServiceforEC2Role
IAM ポリシーの許可のミニマリストに制限することをお勧めします。
Amazon EC2 インスタンスは、タスクのロールを使用するために、コンテナエージェントのバージョン 1.11.0
以上が必要です。ただし、最新のコンテナエージェントのバージョンを使用することをお勧めします。エージェントのバージョンの確認と最新バージョンへの更新については、「Amazon ECS コンテナエージェントをアップデートする」を参照してください。Amazon ECS に最適化された AMI を使用している場合、インスタンスには、ecs-init
パッケージの 1.11.0-1
以降が必要です。インスタンスが最新 Amazon ECS に最適化された AMI を使用している場合、コンテナエージェントおよび ecs-init
の必要なバージョンが含まれます。詳細については、「Amazon ECS に最適化された Linux AMI」を参照してください。
コンテナインスタンスで Amazon ECS に最適化された AMI を使用していない場合、エージェントを開始する --net=host
コマンドと、目的の設定に次のエージェント設定変数に docker run オプションを追加してください (詳細については、「Amazon ECS コンテナエージェントの設定」を参照してください)。
ECS_ENABLE_TASK_IAM_ROLE=true
-
bridge
およびdefault
のネットワークモードに設定されたコンテナのタスク用の、IAM ロールを使用します。 ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=true
-
host
ネットワークモードに設定されたコンテナのタスク用の、IAM ロールを使用します。この変数はエージェントバージョン 1.12.0 以降でのみサポートされています。
実行コマンドの例の詳細については、「Amazon ECS コンテナエージェントの手動更新(Amazon ECS 最適化以外の AMI の場合)」を参照してください。また、タスクのコンテナが AWS 認証情報を取得できるよう、次のネットワーキングコマンドをコンテナインスタンスで設定する必要があります。
sudo sysctl -w net.ipv4.conf.all.route_localnet=1
sudo iptables -t nat -A PREROUTING -p tcp -d 169.254.170.2 --dport 80 -j DNAT --to-destination 127.0.0.1:51679
sudo iptables -t nat -A OUTPUT -d 169.254.170.2 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 51679
再起動後も有効にするには、コンテナインスタンスにこれらの iptables ルールを保存する必要があります。iptables-save および iptables-restore コマンドを使用して、iptables ルールを保存し、起動時にそのルールを復元します。詳細については、特定のオペレーティングシステムのドキュメントを参照してください。
awsvpc
ネットワークモードを使用するタスクで実行されたコンテナが、Amazon EC2 のインスタンスプロファイルに入力されている認証情報にアクセスを防止するためには (タスクロールで指定されている許可は有効)、エージェントの設定 ファイルで ECS_AWSVPC_BLOCK_IMDS
エージェント 設定変数を true
に設定し、そのエージェントを再起動します。詳細については、「Amazon ECS コンテナエージェントの設定」を参照してください。
bridge
ネットワークモードを使用するタスクで実行されたコンテナが、Amazon EC2 のインスタンスプロファイルに入力されている認証情報にアクセスを防止するためには (タスクロールで指定されている許可は有効)、Amazon EC2 インスタンスで次の iptables コマンドを実行します。このコマンドは、host
または awsvpc
ネットワークモードを使用するタスク内のコンテナに影響を与えることはありません。詳細については、「ネットワークモード」を参照してください。
-
sudo yum install -y iptables-services; sudo iptables --insert DOCKER-USER 1 --in-interface docker+ --destination 169.254.169.254/32 --jump DROP
再起動後も有効にするには、Amazon EC2 インスタンスでこの iptables ルールを保存する必要があります。Amazon ECS に最適化された AMI を使用する場合は、次のコマンドを使用します。他のオペレーティングシステムの場合、そのオペレーティングシステムのドキュメントを参照してください。
sudo iptables-save | sudo tee /etc/sysconfig/iptables && sudo systemctl enable --now iptables
外部インスタンスの追加設定
外部インスタンスは、タスクの IAM ロールを使用にするために、コンテナエージェントのバージョン 1.11.0
以上が必要ですが、最新のコンテナエージェントのバージョンを使用することをお勧めします。エージェントのバージョンの確認と最新バージョンへの更新については、「Amazon ECS コンテナエージェントをアップデートする」を参照してください。Amazon ECS に最適化された AMI を使用している場合、インスタンスは、1.11.0-1
パッケージの ecs-init
バージョン以降が必要です。インスタンスが最新 Amazon ECS に最適化された AMI を使用している場合、コンテナエージェントおよび ecs-init
の必要なバージョンが含まれます。詳細については、「Amazon ECS に最適化された Linux AMI」を参照してください。
コンテナインスタンスで Amazon ECS に最適化された AMI を使用していない場合、エージェントを開始する --net=host
コマンドと、目的の設定に次のエージェント設定変数に docker run オプションを追加してください (詳細については、「Amazon ECS コンテナエージェントの設定」を参照してください)。
ECS_ENABLE_TASK_IAM_ROLE=true
-
bridge
およびdefault
のネットワークモードに設定されたコンテナのタスク用の、IAM ロールを使用します。 ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=true
-
host
ネットワークモードに設定されたコンテナのタスク用の、IAM ロールを使用します。この変数はエージェントバージョン 1.12.0 以降でのみサポートされています。
実行コマンドの例の詳細については、「Amazon ECS コンテナエージェントの手動更新(Amazon ECS 最適化以外の AMI の場合)」を参照してください。また、タスクのコンテナが AWS 認証情報を取得できるよう、次のネットワーキングコマンドをコンテナインスタンスで設定する必要があります。
sudo sysctl -w net.ipv4.conf.all.route_localnet=1
sudo iptables -t nat -A PREROUTING -p tcp -d 169.254.170.2 --dport 80 -j DNAT --to-destination 127.0.0.1:51679
sudo iptables -t nat -A OUTPUT -d 169.254.170.2 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 51679
再起動後も有効にするには、コンテナインスタンスにこれらの iptables ルールを保存する必要があります。iptables-save および iptables-restore コマンドを使用して、iptables ルールを保存し、起動時にそのルールを復元します。詳細については、特定のオペレーティングシステムのドキュメントを参照してください。
Amazon EC2 Windows インスタンスの追加設定
重要
これは、タスクロールを使用する EC2 上にある Windows コンテナにのみ適用されます。
Windows 機能を使用するタスクロールには EC2 での追加設定が必要です。
-
コンテナインスタンスを起動する際に、コンテナインスタンスのユーザーデータスクリプトの
-EnableTaskIAMRole
オプションを設定して、この機能を有効にする必要があります。EnableTaskIAMRole
は、タスクの Task IAM ロール機能をオンにします。例:<powershell> Import-Module ECSTools Initialize-ECSAgent -Cluster '
windows
' -EnableTaskIAMRole </powershell> -
Amazon ECS コンテナブートストラップスクリプト に提供されているネットワーキングコマンドを使用してコンテナをブートストラップする必要があります。
-
タスク用の IAM ロールとポリシーを作成する必要があります。詳細については、「タスクの IAM ロールを作成する」を参照してください。
-
タスク認証情報プロバイダーの IAM ロールは、コンテナインスタンスのポート 80 を使用します。したがって、コンテナインスタンスでタスクの IAM ロールを設定にすると、コンテナはポートマッピングのホストポートにポート 80 を使用できません。コンテナをポート 80 で公開するには、負荷分散を使用するサービスをコンテナ用に設定することをお勧めします。ロードバランサーのポート 80 を使用できます。これにより、コンテナインスタンス上の別のホストポートにトラフィックをルーティングできます。詳細については、「ロードバランサーを使用して Amazon ECS サービストラフィックを分散する」を参照してください。
-
Windows インスタンスが再起動された場合は、プロキシインターフェイスを削除して、Amazon ECS コンテナエージェントを再度初期化し、認証情報プロキシを元に戻す必要があります。
Amazon ECS コンテナブートストラップスクリプト
コンテナからコンテナインスタンスの認証情報プロキシにアクセスする前に、必要なネットワーキングコマンドを使用してコンテナをブートストラップする必要があります。起動時にコンテナで次のコードのサンプルスクリプトを実行する必要があります。
注記
Windows で awsvpc
ネットワークモードを使用している場合は、このスクリプトを実行する必要はありません。
Powershell を含む Windows コンテナを実行する場合は、次のスクリプトを使用します。
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"). You may # not use this file except in compliance with the License. A copy of the # License is located at # # http://aws.amazon.com/apache2.0/ # # or in the "license" file accompanying this file. This file is distributed # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either # express or implied. See the License for the specific language governing # permissions and limitations under the License. $gateway = (Get-NetRoute | Where { $_.DestinationPrefix -eq '0.0.0.0/0' } | Sort-Object RouteMetric | Select NextHop).NextHop $ifIndex = (Get-NetAdapter -InterfaceDescription "Hyper-V Virtual Ethernet*" | Sort-Object | Select ifIndex).ifIndex New-NetRoute -DestinationPrefix 169.254.170.2/32 -InterfaceIndex $ifIndex -NextHop $gateway -PolicyStore ActiveStore # credentials API New-NetRoute -DestinationPrefix 169.254.169.254/32 -InterfaceIndex $ifIndex -NextHop $gateway -PolicyStore ActiveStore # metadata API
コマンドシェルのみを持つ Windows コンテナを実行する場合は、次のスクリプトを使用します。
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"). You may # not use this file except in compliance with the License. A copy of the # License is located at # # http://aws.amazon.com/apache2.0/ # # or in the "license" file accompanying this file. This file is distributed # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either # express or implied. See the License for the specific language governing # permissions and limitations under the License. for /f "tokens=1" %i in ('netsh interface ipv4 show interfaces ^| findstr /x /r ".*vEthernet.*"') do set interface=%i for /f "tokens=3" %i in ('netsh interface ipv4 show addresses %interface% ^| findstr /x /r ".*Default.Gateway.*"') do set gateway=%i netsh interface ipv4 add route prefix=169.254.170.2/32 interface="%interface%" nexthop="%gateway%" store=active # credentials API netsh interface ipv4 add route prefix=169.254.169.254/32 interface="%interface%" nexthop="%gateway%" store=active # metadata API