Fargate の Amazon ECS タスクから他の AWS サービスにアクセスする方法を教えてください。

所要時間3分
0

AWS Fargate の Amazon Elastic Container Service (Amazon ECS) タスクから他の AWS サービスにアクセスしたいと考えています。

簡単な説明

AWS API を呼び出すとき、コンテナ化されたアプリケーションは AWS 認証情報を使用して AWS API リクエストに署名する必要があります。Amazon ECS タスクの場合、AWS アイデンティティとアクセス管理 (IAM) タスクロールを使用し、AWS 認証情報を使用して API リクエストに署名します。次に、IAM ロールを Amazon ECS タスク定義または RunTask API オペレーションに関連付けます。これを行うと、コンテナは AWS SDK または AWS コマンドラインインターフェイス (AWS CLI) を使用して、承認された AWS サービスに API リクエストを行うことができます。

**注:**AWS CLI コマンドを実行したときにエラーが発生した場合は、AWS CLI の最新バージョンを使用していることを確認してください
この記事の解決方法の例は、Fargate 上で動作し、Amazon Simple Storage Service (Amazon S3) にアクセスする必要があるアプリケーションを対象としています。

解決方法

前提条件

  • Fargate タスクがアクセスする必要がある AWS サービスを特定します。次に、IAM ロールを作成し、コンテナ内で API 呼び出しを行うために必要なアクションを含むポリシーを指定します。
  • アプリケーションコンテナのタスク定義を作成し、taskRoleArn IAM パラメータを使用してタスクの IAM ロールを指定します。

タスク用の IAM ポリシーとロールを作成する

1.    データを保存する Amazon S3 バケットを作成します。バケット名は固有で、Amazon S3 バケットのバケット名の要件に従っている必要があります。詳細については、「バケット命名ルール」を参照してください。

2.    タスク用の IAM ポリシーとロールを作成します。この例では、アプリケーションはオブジェクトを S3 バケットに入れ、それらのオブジェクトを一覧表示するために必要です。

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "S3PutGEList",
    "Effect": "Allow",
    "Action": ["s3:PutObject", "s3:GetObject", "s3:ListBucketMultipartUploads", "s3:ListBucketVersions", "s3:ListBucket", "s3:ListMultipartUploadParts"],
    "Resource": ["arn:aws:s3:::*/*", "arn:aws:s3:::kc-test-fargate-app-bucket"]
  }]
}

**注:**fargate-app-bucket を S3 バケットの名前で置き換えてください。

アプリケーションのタスク定義を作成し、タスクの IAM ロールを指定する

タスク定義の作成時にロールを割り当てるには、taskRoleArn セクションを使用してください。

{
  "containerDefinitions": [{
    "name": "sample-s3-access",
    "image": "public.ecr.aws/aws-cli/aws-cli:latest",
    "memory": 1024,
    "cpu": 512,
    "command": ["s3api", "put-object", "--bucket", "fargate-app-bucket", "--key", "/usr/local/bin/aws"],
    "essential": true
  }],
  "memory": "1024",
  "cpu": "512",
  "requiresCompatibilities": ["FARGATE"],
  "networkMode": "awsvpc",
  "runtimePlatform": {
    "operatingSystemFamily": "LINUX"
  },
  "family": "s3_access-WITH-ROLE",
  "taskRoleArn": "arn:aws:iam::aws_account_id:role/s3-access-role"
}

**注:**ベースイメージには aws-cli インストール (public.ecr.aws/aws-cli/aws-cli:latest) が含まれているため、このアプリケーションは API 呼び出しを行うことができます。

設定情報をファイルに保存し、register-task-definition コマンドを使用してタスク定義を登録します。

aws ecs register-task-definition --cli-input-json file://task-def1.json --region eu-west-1

スタンドアロンタスクを作成して実行する

スタンドアロンタスクを実行するには、Fargate 起動タイプを使用します。この例では、コンテナはコマンドで実行され、終了します。

コンテナがコマンドを実行した後、taskRoleArn にAPI 呼び出しの実行に必要な権限がある場合、タスクは ExitCode=0 を返します。taskRoleArn が見つからないか、権限が不十分な場合、タスクは none 0 exit コードを返します。

サービスを作成する

**注:**サービスが安定した状態になるためには、タスクプロセスを開始時に終了することはできません。前の例では、コンテナはコマンドが完了すると終了します。そのため、この例はサービスの一部として実行するのには適していません。

1.    ループを実行し、ファイルの作成日とホスト名をファイルに出力する bash スクリプトを作成します。次に、ファイルを Amazon S3 バケットにプッシュします。

以下の例では、bash スクリプトの名前は「run-s3-script.sh」です。

#!/bin/bash

while true; do
TODAY=$(date)
echo "-----------------------------------------------------"
echo "Date: $TODAY Host:$HOST"
echo "File was added and active on these Dates: $TODAY" from Host:$HOSTNAME>> checkfile.txt
echo "--------------------Add to S3------------------------"
aws s3 cp checkfile.txt s3://kc-test-fargate-app-bucket
status_code=$?
echo "------------Get upload StatusCode=$status_code ([ $status_code -eq 0 ] means failed)---------------"
#echo "------------Get upload StatusCode=$status_code and exit if upload failed.---------------"
#[ $status_code -eq 0 ] || exit 1
echo "------------Also list the files in the S3 bucket---------------"
aws s3 ls s3://kc-test-fargate-app-bucket
status_code=$?
echo "------------Get the status_code=$status_code after listing objects in bucket---------------"
#[ $status_code -eq 0 ] || exit 1 #uncomment this is you want the task to stop upon failed attempt
echo "============================================================================="
sleep 5

#check the user or role that made the call
aws sts get-caller-identity
echo "*****End of loop, restarting"
sleep 10

done

2.    スクリプトを追加して実行する新しいイメージを作成するには、Dockerfile を作成します。

FROM public.ecr.aws/amazonlinux/amazonlinux:latest
Run yum -y install unzip
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN /aws/install
RUN rm -rf aws*
COPY run-s3-test.sh /
CMD ./run-s3-test.sh

3.    イメージをローカルでビルドするには、以下のコマンドを実行します。

$ docker build -t test-awscli:amz-build-scripts

4.    イメージをAmazon Elastic Container Registry (Amazon ECR) にプッシュします。サービスの作成に使用するタスク定義にイメージを追加します。詳細については、「イメージをプッシュする」を参照してください。

{
  "containerDefinitions": [{
    "name": "add-files-to-s3",
    "image": "aws_account_id.dkr.ecr.eu-central-1.amazonaws.com/test-s3-ecs:amzlin-build-scripts",
    "memory": 1024,
    "cpu": 512,
    "healthCheck": {
      "retries": 3,
      "command": ["CMD-SHELL", "aws s3 ls s3://kc-test-fargate-app-bucket || exit 1"],
      "timeout": 5,
      "interval": 10,
      "startPeriod": 5
    },
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "/ecs/test-s3-script",
        "awslogs-region": "eu-central-1",
        "awslogs-create-group": "true",
        "awslogs-stream-prefix": "ecs"
      }
    },
    "essential": true
  }],
  "memory": "1024",
  "cpu": "512",
  "requiresCompatibilities": ["FARGATE"],
  "networkMode": "awsvpc",
  "runtimePlatform": {
    "operatingSystemFamily": "LINUX"
  },
  "family": "test-s3-script",
  "taskRoleArn": "arn:aws:iam::aws_account_id:role/s3-access-role",
  "executionRoleArn": "arn:aws:iam::aws_account_id:role/ecsTaskExecutionRole"
}

**注:**コンテナに IAM タスクロールを使用すると、「アクセス拒否」エラーが表示されることがあります。詳細については、「Amazon ECS で「アクセス拒否」エラーを発生させないように IAM タスクロールを設定するにはどうすればよいですか?」をご覧ください。

関連情報

コンソールを使用してサービスを作成する

AWS公式
AWS公式更新しました 9ヶ月前