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

使用IAM用户创建ECS CloudFormation栈时遇AccessDeniedException错误求助

Amazon ECS CloudFormation嵌套栈创建时AccessDeniedException错误排查

错误信息

错误: Resource handler returned message: "Invalid request provided: CreateService error: Access denied (Service: AmazonECS; Status Code: 400; Error Code: AccessDeniedException; Request ID: c894016a-395d-4468-92fa-b63a2a4642f9; Proxy: null)" (RequestToken: 5d151803-6b53-02ea-8903-7c34934b251e, HandlerErrorCode: InvalidRequest)

问题背景

使用CloudFormation嵌套栈创建Amazon ECS服务时触发上述访问拒绝错误,导致栈创建失败。已尝试单独创建ExecutionRole等网络方案,均未解决;使用root账号可成功创建该栈,但切换为IAM用户时就会出现访问拒绝错误。

ECS子栈模板代码

---
AWSTemplateFormatVersion: '2010-09-09'
Description: The template used to create an ECS Service from the ECS Console.
Parameters:
  ECSClusterName:
    Type: String
    Default: ecs-tutorial
  ECSServiceName:
    Type: String
    Default: ecs-tutorial-td
  LoadBalancerName:
    Type: String
    Default: ecs-tutorial-lb
  WAFName:
    Type: String
    Default: AllowAllTrafficAcl

Resources:
  ECSService:
    Type: AWS::ECS::Service
    Properties:
      Cluster: ecs-tutorial
      CapacityProviderStrategy:
      - CapacityProvider: FARGATE
        Base: 0
        Weight: 1
      TaskDefinition: !Ref TaskDefinition #arn:aws:ecs:us-east-1:818971154557:task-definition/ecs-tutorial-td:1
      ServiceName: ecs-tutorial-td
      # SchedulingStrategy: REPLICA
      DesiredCount: 2
      LoadBalancers:
      - ContainerName: tindog
        ContainerPort: 80
        LoadBalancerName:
          Ref: AWS::NoValue
        TargetGroupArn:
          Ref: TargetGroup
      NetworkConfiguration:
        AwsvpcConfiguration:
          # AssignPublicIp: ENABLED
          SecurityGroups: !Split [",", !ImportValue ECSSecurityGroup]
          Subnets:
            - !ImportValue PrivateSubnet1Id
            - !ImportValue PrivateSubnet2Id
      DeploymentController:
        Type: ECS
    DependsOn:
    - Listener

  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: tindog-website-family
      # TaskRoleArn: !ImportValue ECSTaskRoleARN  # Import the IAM role ARN from another stack
      Cpu: 512 #0.5cpu
      Memory: 1024  #1gb
      NetworkMode: awsvpc
      # ExecutionRoleArn: !ImportValue ECSTaskRoleARN 
      ContainerDefinitions:
        - Name: tindog
          Image: paranjay1/tindog:latest
          PortMappings:
            - ContainerPort: 80

      RequiresCompatibilities:
        - EC2
        - FARGATE

  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Type: application
      Name: ecs-tutorial-lb
      SecurityGroups: !Split [",", !ImportValue ECSSecurityGroup]
      Subnets:
        - !ImportValue PublicSubnet1Id
        - !ImportValue PublicSubnet2Id

  TargetGroup:
    DependsOn: LoadBalancer
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckPath: "/"
      HealthCheckProtocol: HTTP
      Name: ecs-tutorial-target-group
      Port: 80
      Protocol: HTTP
      TargetType: ip
      VpcId: !ImportValue VPCID
      TargetGroupAttributes:
      - Key: deregistration_delay.timeout_seconds
        Value: '300'

  Listener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
      - Type: forward
        TargetGroupArn:
          Ref: TargetGroup
      LoadBalancerArn:
        Ref: LoadBalancer
      Port: 80
      Protocol: HTTP

  MyWAFWebACL:
    Type: AWS::WAFv2::WebACL
    DependsOn: LoadBalancer
    Properties:
      Name: !Ref WAFName 
      Scope: REGIONAL
      DefaultAction:
        Allow: {}  # An empty Allow block allows all traffic 
      VisibilityConfig:
        CloudWatchMetricsEnabled: true  # Enable CloudWatch metrics collection
        MetricName: MyWafMetric  # Define a metric name for WAF logs
        SampledRequestsEnabled: true  # Enable capturing a sample of requests for analysis

  MyWAFWebACLAsgn:
    DependsOn: MyWAFWebACL
    Type: AWS::WAFv2::WebACLAssociation
    Properties:
      WebACLArn: !GetAtt MyWAFWebACL.Arn
      ResourceArn: !Ref LoadBalancer
  
Outputs:
  ClusterName:
    Description: The cluster used to create the service.
    Value:
      Ref: ECSClusterName
  ECSService:
    Description: The created service.
    Value:
      Ref: ECSService
  LoadBalancer:
    Description: The created load balancer.
    Value:
      Ref: LoadBalancer
  Listener:
    Description: The created listener.
    Value:
      Ref: Listener
  TargetGroup:
    Description: The created target group.
    Value:
      Ref: TargetGroup
  LoadBalancerDNSName:
    Description: The DNS name of the load balancer.
    Value: !GetAtt LoadBalancer.DNSName
    Export:
      Name: LoadBalancerDNSName
  LoadBalancerARN:
    Description: "ALB ARN"
    Value: !GetAtt LoadBalancer.LoadBalancerArn
    Export:
      Name: "LoadBalancerARN"

IAM用户权限情况

当前使用的IAM用户已附加相关权限(权限截图显示用户拥有ECS、CloudFormation、ELB等相关权限)

可能原因及解决方案

1. IAM用户缺少ECS服务创建的关键权限

虽然截图显示有部分权限,但可能缺少以下核心权限:

  • ecs:CreateService:直接创建ECS服务的权限
  • ecs:RegisterTaskDefinition:创建任务定义的权限
  • iam:PassRole:CloudFormation需要传递任务执行角色/任务角色给ECS的权限(即使模板中注释了RoleArn,Fargate模式下仍可能需要基础的执行角色权限)
  • 同时需要确保权限策略中包含对应的资源,避免资源范围限制过严。

2. 嵌套栈的权限传递问题

嵌套栈的执行角色(如果指定了)可能缺少权限,或者没有为IAM用户授予cloudformation:CreateStack权限以创建嵌套子栈,同时子栈创建时需要的所有资源权限都要传递给IAM用户或嵌套栈角色。

3. 任务定义的执行角色配置缺失

模板中TaskDefinition的ExecutionRoleArn被注释掉,Fargate模式下ECS任务需要执行角色来拉取镜像、访问日志等资源。即使手动创建了ExecutionRole,需要确保:

  • 角色信任策略允许ECS服务(ecs-tasks.amazonaws.com)执行sts:AssumeRole
  • IAM用户拥有iam:PassRole权限传递该执行角色给ECS
  • 在模板中正确引用该执行角色的ARN,取消注释ExecutionRoleArn配置

4. 资源依赖或跨栈引用权限

模板中使用了!ImportValue导入其他栈的资源(如安全组、子网),需要确保IAM用户拥有访问这些导入资源的权限,或者跨栈导出的资源权限配置正确。

具体操作步骤

  1. 为IAM用户补充以下权限策略(根据实际情况调整资源范围):
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecs:CreateService",
                "ecs:RegisterTaskDefinition",
                "ecs:DescribeClusters",
                "ecs:DescribeTaskDefinitions"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::ACCOUNT_ID:role/ECS_EXECUTION_ROLE_NAME"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DescribeStacks",
                "cloudformation:DescribeStackResources"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:CreateLoadBalancer",
                "elasticloadbalancing:CreateTargetGroup",
                "elasticloadbalancing:CreateListener",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeTargetGroups"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "wafv2:CreateWebACL",
            "Resource": "*"
        }
    ]
}
  1. 修复ECS任务定义的执行角色配置:
    • 取消TaskDefinition中ExecutionRoleArn的注释,确保引用正确的执行角色ARN
    • 验证执行角色的信任策略包含:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
  1. 检查嵌套栈的执行配置:如果使用了CloudFormation服务角色,确保该角色拥有所有子栈资源创建的权限;如果没有使用服务角色,确保IAM用户拥有所有嵌套栈涉及的资源权限。

内容的提问来源于stack exchange,提问作者PARANJAY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:57:08