1

我在正确配置 Lambda 以运行批处理作业时遇到问题。代码如下所示:

client = boto3.client('batch')

_job_queue = os.environ['JOB_QUEUE']
_job_definition = os.environ['JOB_DEFINITION']
_job_name = os.environ['START_JOB_NAME']

def lambda_handler(event, context):
    return start_job()

def start_job():
    response = client.list_jobs(jobQueue=_job_queue)
    if _job_name in [job.jobName for job in response['jobSummaryList']]:
        return 200

    try:
        client.submit_job(jobName=_job_name, jobQueue=_job_queue, jobDefinition=_job_definition)
        return 201
    except:
        return 400

它在client.list_jobs(jobQueue=_job_queue)上失败,并出现以下错误:

“errorMessage”:“调用 ListJobs 操作时发生错误 (AccessDeniedException):用户:arn:aws:sts::749340585813:assumed-role/myproject/dev-StartJobLambda-HZO22Z5IMTFB 无权执行:batch:ListJobs on resource : arn:aws:batch:us-west-2:749340585813:/v1/listjobs",

如果我将访问密钥添加到上面的 lambda,它工作正常。我认为这是因为我具有管理员访问权限,并且以我的用户身份进行身份验证为 lambda 提供了我的特权。

我的 lambda 定义如下所示:

"StartJobLambda": {
  "Type": "AWS::Lambda::Function",
  "Properties": {
    "Description": "Starts the My Project model training job.",
    "Role": {
      "Fn::GetAtt": [
        "StartJobRole",
        "Arn"
      ]
    },
    "Runtime": "python3.6",
    "Handler": {
      "Fn::Sub": "${StartJobModule}.lambda_handler"
    },
    "Tags": [
      {
        "Key": "environment",
        "Value": {
          "Ref": "Environment"
        }
      },
      {
        "Key": "project",
        "Value": "myproject"
      }
    ],
    "Environment": {
      "Variables": {
        "JOB_QUEUE": {
          "Ref": "JobQueue"
        },
        "JOB_DEFINITION": {
          "Ref": "TrainingJob"
        }
      }
    },
    "Code": {
      "S3Bucket": {
        "Ref": "CodeBucket"
      },
      "S3Key": {
        "Ref": "StartJobKey"
      }
    },
    "VpcConfig": {
      "SubnetIds": [
        {
          "Fn::ImportValue": {
            "Fn::Sub": "${NetworkStackNameParameter}-PrivateSubnet"
          }
        },
        {
          "Fn::ImportValue": {
            "Fn::Sub": "${NetworkStackNameParameter}-PrivateSubnet2"
          }
        }
      ],
      "SecurityGroupIds": [
        {
          "Fn::ImportValue": {
            "Fn::Sub": "${NetworkStackNameParameter}-TemplateSecurityGroup"
          }
        }
      ]
    }
  }
}

还会创建以下角色和策略:

"StartJobRole": {
  "Type": "AWS::IAM::Role",
  "Properties": {
    "RoleName": "myproject-start-job",
    "AssumeRolePolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Service": [
              "lambda.amazonaws.com"
            ]
          },
          "Action": [
            "sts:AssumeRole"
          ]
        }
      ]
    },
    "Path": "/"
  }
},
"StartJobBatchPolicy": {
  "Type": "AWS::IAM::Policy",
  "Properties": {
    "PolicyName": "start-job-batch-policy",
    "PolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "batch:ListJobs",
            "batch:SubmitJob"
          ],
          "Resource": [
            {
              "Ref": "JobQueue"
            }
          ]
        }
      ]
    },
    "Roles": [
      {
        "Ref": "StartJobRole"
      }
    ]
  }
}

此外,还有一个角色可以让 lambda 在 VPC 上运行:

"LambdaVPCExecutionRole": {
  "Type": "AWS::IAM::Role",
  "Properties": {
    "RoleName": "myproject-lambda-vpc-execution-role",
    "AssumeRolePolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Service": [
              "lambda.amazonaws.com"
            ]
          },
          "Action": [
            "sts:AssumeRole"
          ]
        }
      ]
    },
    "Path": "/"
  }
},
"LambdaVPCExecutionPolicy": {
  "Type": "AWS::IAM::Policy",
  "Properties": {
    "PolicyName": "lambda-vpc-execution-policy",
    "PolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
          ],
          "Resource": "arn:aws:logs:*:*:*"
        },
        {
          "Effect": "Allow",
          "Action": [
            "ec2:CreateNetworkInterface",
            "ec2:DescribeNetworkInterfaces",
            "ec2:DeleteNetworkInterface"
          ],
          "Resource": "*"
        }
      ]
    },
    "Roles": [
      {
        "Ref": "LambdaVPCExecutionRole"
      },
      {
        "Ref": "StartJobRole"
      }
    ]
  }
},
4

1 回答 1

1

这是 CloudFormation 需要改进的地方。一些 AWS 服务还不允许资源级权限,当您尝试创建它们时,您的堆栈将成功!. 对于 IAM 相关问题,有时您需要进入控制台并验证您的策略未处于警告状态。AWS 至少会标记那些试图对不允许的服务应用资源级别权限的策略。

例如,对于 DynamoDB,您必须授予对所有表的访问权限。您不能限制或限制对单个表的访问。如果您尝试创建 cloudformation IAM 策略,它不会失败,但不会达到您想要的效果。

于 2018-02-23T08:46:02.090 回答