创建 CloudFront Distribution 时出现 Crypp CloudFormation 失败

2024-05-10

我设置了一个 CloudFormation 模板来跟踪 CloudFront 分发等。设置完毕后,我创建了一个AWS::CertificateManager::Certificate and an AWS::CloudFront::Distribution资源,其中 CDN 仅从非网站 S3 源提供服务。

When I run the change set, I get this incredibly vague failure. enter image description here "Access denied for operation 'AWS::CloudFront::Distribution'." kind of loses me here. For one thing, it's not clear to me what operation this is supposed to be. On top of that, the stack rollback after this is incomplete. The CloudFormation events don't even show an attempt to remove the CDN or the cert, and when I try to hit the CloudFront URL from my browser, it works flawlessly, so I am not even sure what my template was trying to do here that failed. In fact, the only reason this is an issue for me is because the incomplete rollback tries to revert my lambdas in the stack to nodejs8.10, which causes larger failures. If that weren't an issue, I don't know that I would feel the effects of this vague error.

模板,基于几年前的静态站点示例:

AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::CodeStar

Parameters:
  ProjectId:
    Type: String
    Description: AWS CodeStar projectID used to associate new resources to team members
  CodeDeployRole:
    Type: String
    Description: IAM role to allow AWS CodeDeploy to manage deployment of AWS Lambda functions
  Stage:
    Type: String
    Description: The name for a project pipeline stage, such as Staging or Prod, for which resources are provisioned and deployed.
    Default: ''

Globals:
  Api:
    BinaryMediaTypes:
      - image~1png
  Function:
    Runtime: nodejs14.x
    AutoPublishAlias: live
    DeploymentPreference:
      Enabled: true
      Type: Canary10Percent5Minutes
      Role: !Ref CodeDeployRole

Resources:

  MahCert:
    Type: AWS::CertificateManager::Certificate
    Properties:
      DomainName: domain.com
      DomainValidationOptions:
        - DomainName: domain.com
          HostedZoneId: Z2GZX5ZQI1HO5L
      SubjectAlternativeNames:
        - '*.domain.com'
      CertificateTransparencyLoggingPreference: ENABLED
      ValidationMethod: DNS

  CloudFrontCDN:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Comment: Source for all static resources
        PriceClass: PriceClass_100
        Aliases:
          - domain.com
        ViewerCertificate:
          AcmCertificateArn: !Ref MahCert
          MinimumProtocolVersion: TLSv1.2_2021
          SslSupportMethod: sni-only
        DefaultRootObject: index.html
        DefaultCacheBehavior:
          ViewerProtocolPolicy: redirect-to-https
          CachePolicyId: b2884449-e4de-46a7-ac36-70bc7f1ddd6d
          TargetOriginId: SiteBucket
        Enabled: True
        Origins:
          - DomainName: <my_bucket>.s3.amazonaws.com
            Id: SiteBucket
            S3OriginConfig:
              OriginAccessIdentity: ''

  ServerlessRestApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      DefinitionBody:
        swagger: 2.0
        info:
          title: Static resource proxy

        paths:
          /static/{proxy+}:
            get:
              x-amazon-apigateway-integration:
                httpMethod: ANY
                type: http_proxy
                uri: <my_bucket>.s3.amazonaws.com/static/{proxy}
              responses: {}

  GetHelloWorld:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.get
      Role:
        Fn::GetAtt:
        - LambdaExecutionRole
        - Arn
      Events:
        GetEvent:
          Type: Api
          Properties:
            Path: /
            Method: get
        ProxyEvent:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: any
            
  GetStaticContent:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.getResource
      Role:
        Fn::GetAtt:
        - LambdaExecutionRole
        - Arn
      Events:
        GetResourceEvent:
          Type: Api
          Properties:
            Path: /static/{folder}/{file}
            Method: get
            
  GetQuote:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.getQuote
      Role:
        Fn::GetAtt:
        - LambdaDynamoDBReadRole
        - Arn
      Events:
        GetRandomQuoteEvent:
          Type: Api
          Properties:
            Path: /getquote
            Method: get
        GetQuoteEvent:
          Type: Api
          Properties:
            Path: /getquote/{id}
            Method: get
            
  LambdaExecutionRole:
    Description: Creating service role in IAM for AWS Lambda
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub 'CodeStar-${ProjectId}-Execution${Stage}'
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: [lambda.amazonaws.com]
          Action: sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
      PermissionsBoundary: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/CodeStar_${ProjectId}_PermissionsBoundary'
      
  LambdaDynamoDBReadRole:
    Description: Creating service role in IAM for AWS Lambda
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub '${ProjectId}-DynamoDB-Read'
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: [lambda.amazonaws.com]
          Action: sts:AssumeRole
      Path: /
      Policies:
        -
          PolicyName: "dynamodb-read-quotes"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Action:
                  - "dynamodb:GetItem"
                  - "dynamodb:DescribeTable"
                Resource: "<dynamo_arn>"
      ManagedPolicyArns:
        - !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'

Note - domain.com不是我在这里使用的实际域名。

Updates:

我完全删除了堆栈并从该模板重新创建了它,认为堆栈的历史记录出了问题。但是,我遇到了同样的错误。

The IAM role that the stack uses has these permissions enter image description here

事实上,即使授予该角色对 CloudFront 资源的完全写入访问权限后,问题仍然存在。


基于聊天讨论。

发现问题原因缺失IAM权限用于部署堆栈的 IAM 角色。具体来说,缺少的权限是:

  • cloudfront:GetDistribution- 授予获取有关网络发行版信息的权限

将该权限添加到角色中,solved问题。

为了找到丢失的权限,使用了 CloudTrial 的事件历史记录。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建 CloudFront Distribution 时出现 Crypp CloudFormation 失败 的相关文章

随机推荐