如何配置 AWS lambda 执行角色以能够列出批处理作业?

How to configure AWS lambda execution role to be able to list batch jobs?

我在正确配置我的 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": "An error occurred (AccessDeniedException) when calling the ListJobs operation: User: arn:aws:sts::749340585813:assumed-role/myproject/dev-StartJobLambda-HZO22Z5IMTFB is not authorized to perform: 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"
      }
    ]
  }
}

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

"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"
      }
    ]
  }
},

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

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