You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为AWS Batch Fargate作业授予S3与DynamoDB访问权限?

问题分析与解决方案

错误原因

你遇到的Unable to get IAM security credentials from EC2 Instance Metadata Service错误,核心问题是混淆了AWS Batch Fargate作业的两种IAM角色:执行角色(executionRole)和任务角色(jobRole),且未正确为容器应用配置任务角色:

  • executionRole:仅负责任务执行层面的操作,比如拉取ECR镜像、写入CloudWatch日志,不需要S3/DynamoDB权限。
  • jobRole:才是容器内应用代码用来访问AWS服务(S3、DynamoDB)的角色,应用通过任务角色获取凭证,而非EC2元数据服务。

你的代码把两种角色的职责混在一起,只指定了executionRole,却未配置jobRole,导致应用无法获取合法访问凭证。

修正步骤与代码

1. 拆分执行角色与任务角色

分别创建executionRole和jobRole,明确各自权限范围:

  • executionRole:保留ECR和日志相关权限
  • jobRole:分配S3和DynamoDB的访问权限

2. 在JobDefinition中同时配置两个角色

在容器配置里分别指定executionRole和jobRole属性,让Fargate正确加载对应角色的凭证。

修正后的完整代码

import { ComputeEnvironment, ComputeResourceType, JobDefinition, JobQueue, PlatformCapabilities } from "@aws-cdk/aws-batch-alpha";
import { Duration, Stack, StackProps } from "aws-cdk-lib";
import { ITable } from "aws-cdk-lib/aws-dynamodb";
import { IVpc } from "aws-cdk-lib/aws-ec2";
import { ContainerImage } from "aws-cdk-lib/aws-ecs";
import { PolicyDocument, PolicyStatement, Role, ServicePrincipal } from "aws-cdk-lib/aws-iam";
import { IBucket } from "aws-cdk-lib/aws-s3";
import { Construct } from "constructs";
import { stage } from "..";

export interface CapsJobStackProps extends StackProps {
    mainBucket: IBucket;
    capsTable: ITable;
    vpc: IVpc
}

export class CapsJobStack extends Stack {
    constructor(scope: Construct, id: string, private props: CapsJobStackProps) {
      super(scope, id, props);

      const computeEnvironment = new ComputeEnvironment(this, 'CapsComputeEnvironment', {
        computeResources: {
          type: ComputeResourceType.FARGATE,
          vpc: props.vpc,
          maxvCpus: 2
        },
      });

      const jobQueue = new JobQueue(this, 'CapsJobQueue', {
        computeEnvironments: [{computeEnvironment, order: 1}]
      });

      // 执行角色:负责镜像拉取、日志写入等任务执行操作
      const executionRole = new Role(this, 'CapsExecutionRole', {
        assumedBy: new ServicePrincipal("ecs-tasks.amazonaws.com"),
        inlinePolicies: {
          EcsExecution: new PolicyDocument({
            statements: [
              new PolicyStatement({
                actions: ["ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "logs:CreateLogStream", "logs:PutLogEvents" ],
                resources: ["*"]
              })
            ]
          })
        }
      });

      // 任务角色:容器应用用来访问S3和DynamoDB的角色
      const jobRole = new Role(this, 'CapsJobRole', {
        assumedBy: new ServicePrincipal("ecs-tasks.amazonaws.com"),
      });
      props.capsTable.grantReadWriteData(jobRole);
      props.mainBucket.grantReadWrite(jobRole);

      const jobDefinition = new JobDefinition(this, 'CapsJob', {
        container: {
          image: ContainerImage.fromAsset('../src/Caps.Uploader', {
            file: 'DockerfileCdk'
          }),
          environment: {
            "OD_ENVIRONMENT": stage,
            "OD_BUCKET": props.mainBucket.bucketName,
            "OD_CAPSTABLE": props.capsTable.tableName
          },
          executionRole: executionRole, // 指定执行角色
          jobRole: jobRole, // 指定任务角色(关键!之前遗漏了这一步)
          vcpus: 0.25,
          memoryLimitMiB: 512
        },
        timeout: Duration.days(1),
        retryAttempts: 3,
        platformCapabilities: [PlatformCapabilities.FARGATE]
      });
    }
}

关键改动说明

  • 拆分executionRole和jobRole,明确各自职责边界
  • 在JobDefinition的容器配置中新增jobRole属性,修正了之前角色混用的问题
  • 任务角色仅保留S3和DynamoDB的权限,执行角色专注于镜像拉取和日志相关操作

这样配置后,容器内的应用就能通过任务角色获取合法IAM凭证,正常访问S3和DynamoDB,同时避免元数据服务相关错误。

内容的提问来源于stack exchange,提问作者Jesús López

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 14:03:22