Lambda无权访问ECR镜像。

20
最近发布了针对Lambda函数的Docker镜像,我决定使用CloudFormation来尝试这个功能。
因此,下面的Lambda函数考虑了存储在Elastic Container Registry中的Docker镜像,并遵循文档中的示例来访问该镜像。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: lambda-docker-image

Globals:
  Function:
    Timeout: 180

Resources:
  DockerAsImage:
    Type: AWS::Serverless::Function 
    Properties:
      FunctionName: DockerAsImage
      ImageUri: ??????????????.dkr.ecr.us-west-2.amazonaws.com/????:latest
      PackageType: Image
      Policies: 
        - Version: '2012-10-17' 
          Statement:
            - Effect: Allow
              Action: 
                - ecr:*
                - ecr-public:*
                - sts:GetServiceBearerToken
              Resource: "*"
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: post

我正在使用samus-west-2部署模板。

sam deploy -t template.yaml --capabilities "CAPABILITY_NAMED_IAM" --region "us-west-2" --stack-name "lambda-docker-example" --s3-bucket "my-bucket" --s3-prefix "sam_templates/lambda-docker-example" --force-upload  --no-confirm-changeset

然而,在IAM角色成功创建后,Lambda函数无法创建,并出现以下错误

Lambda does not have permission to access the ECR image. Check the ECR permissions. (Service: AWSLambdaInternal; Status Code: 403; Error Code: AccessDeniedException;

尽管该角色可以访问任何ecs资源,但我尝试的另一种方法是创建一个单独的角色,并通过Role: !GetAtt Role.Arn将其分配给lambda,这种方法也不起作用。

2
您的IAM用户/角色是否具有使用ECR的权限?为了使用基于镜像的Lambda函数,创建该函数的用户/角色需要ECR权限,如此文档所述。您可以检查一下吗? - Marcin
@Marcin 我也遇到了同样的问题,你的建议解决了它! - alessmar
@alexyz78 謝謝你讓我知道。如果對於原 PO 有幫助,我可以在答案中提供更多信息。 - Marcin
1
@Marcin 是的,这两个权限确实解决了问题,此外,要将Docker镜像推送到ECR,还需要 ecr: InitiateLayerUpload 权限。非常感谢你,Marcin,AWS文档往往不是一个易于理解的指南。欢迎分享你的答案。 - Miguel Trejo
@MiguelTrejo 谢谢,已添加答案。 - Marcin
6个回答

28

根据评论。

要使用基于镜像的Lambda,需要拥有ECR权限的是IAM用户/角色,而不是函数本身。来自文档

确保创建函数的AWS Identity and Access Management(IAM)用户或角色的权限包含AWS托管策略GetRepositoryPolicySetRepositoryPolicy

除了上述两个权限之外,还需要ecr:InitiateLayerUpload权限。


1
嗯,我们似乎还需要 LambdaECRImageRetrievalPolicy - Att Righ

8

如果希望222222222222账户中的Lambda使用11111111111中的ECR镜像,则需要遵循https://aws.amazon.com/blogs/compute/introducing-cross-account-amazon-ecr-access-for-aws-lambda/中的步骤。

IAM中最重要的部分是在11111111111存储库上设置以下存储库策略:

      RepositoryPolicyText:
        Version: "2012-10-17"
        Statement:
          - Sid: CrossAccountPermission
            Effect: Allow
            Action:
              - ecr:BatchGetImage
              - ecr:GetDownloadUrlForLayer
            Principal:
              AWS:
                - arn:aws:iam::222222222222:root
          - Sid: LambdaECRImageCrossAccountRetrievalPolicy
            Effect: Allow
            Action:
              - ecr:BatchGetImage
              - ecr:GetDownloadUrlForLayer
            Principal:
              Service: lambda.amazonaws.com
            Condition:
              StringLike:
                aws:sourceArn:
                  - arn:aws:lambda:us-east-1:222222222222:function:*

4
您需要将以下策略添加到用户和角色中,以便与 AWS Lambda 相关联。该策略可启用 ECR 操作:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ecr:SetRepositoryPolicy",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "ecr:CompleteLayerUpload",
                "ecr:DescribeImages",
                "ecr:DescribeRepositories",
                "ecr:UploadLayerPart",
                "ecr:ListImages",
                "ecr:InitiateLayerUpload",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetRepositoryPolicy",
                "ecr:PutImage"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "ecr:GetAuthorizationToken",
            "Resource": "*"
        }
    ]
}

2
我在拥有所有必要的 AWS Lambda 策略的情况下遇到了同样的问题。帮助我的是在 ECR 中添加权限。
{
      "Sid": "LambdaECRImageRetrievalPolicy",
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": [
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer"
      ]
}   

尽管 AWS 也说,如果 Lambda 具有策略 (ecr:getRepositoryPolicyecr:setRepositoryPolicy),那么我们就不需要在 ECR 中添加权限,Lambda 会自动完成这些操作。
引用如下:
如果 Amazon ECR 存储库不包括这些权限,则 Lambda 会将 ecr:BatchGetImageecr:GetDownloadUrlForLayer 添加到容器映像存储库权限中。只有具有 ecr:getRepositoryPolicyecr:setRepositoryPolicy 权限的主调 Lambda 才能添加这些权限。
参见 参考资料 #1#2

1

遇到过类似的问题,当我在 账户 A 中使用 ECR,并且需要在 账户 B 中创建 Lambda 时。

解决方法是在账户 A 的 ECR 存储库中添加以下内容:

参考链接

{
  "Version": "2008-10-17",
  "Statement": [  
    {
      "Sid": "LambdaECRImageRetrievalPolicyCrossAccount",
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": [
        "ecr:BatchGetImage",
        "ecr:DeleteRepositoryPolicy",
        "ecr:GetDownloadUrlForLayer",
        "ecr:GetRepositoryPolicy",
        "ecr:SetRepositoryPolicy"
      ],
      "Condition": {
        "StringLike": {
          "aws:sourceArn": "arn:aws:lambda:us-east-2:{account_id}:function:*"
        }
      }
    },
    {
      "Sid": "CrossAccountPermission",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::{account_id}:root"
      },
      "Action": [
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer"
      ]
    }
  ]
}

0

我的贡献并没有真正回答OP的问题,但它可能会帮助到寻找解决方案的人 - 如果这是和我的情况相同的话。

通过一些试错(不是通过CloudTrail或AWS的任何文档),我发现问题不在Lambda获取ECR中的图像的权限上,而是要能够设置ECR的策略(ecr:SetRepositoryPolicy),因为有一个SCP明确拒绝。

如果您想查看是否符合您的情况,请尝试访问存储库并更改策略,如果无法更改,则是这样。尝试其他任何事情都没有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接