创建 CloudFront Distribution 时出现隐秘的 CloudFormation 失败

问题描述 投票:0回答:1

我设置了一个 CloudFormation 模板来跟踪 CloudFront 分发等。设置完毕后,我创建了一个

AWS::CertificateManager::Certificate
和一个
AWS::CloudFront::Distribution
资源,其中 CDN 仅从非网站 S3 源提供服务。

当我运行变更集时,我得到了这个令人难以置信的模糊失败。 “操作‘AWS::CloudFront::Distribution’的访问被拒绝。”有点让我迷失在这里。一方面,我不清楚这应该是什么操作。最重要的是,此后的堆栈回滚是不完整的。 CloudFormation 事件甚至没有显示删除 CDN 或证书的尝试,当我尝试从浏览器中访问 CloudFront URL 时,它运行完美,所以我什至不确定我的模板在这里试图做什么失败的。事实上,这对我来说是一个问题的唯一原因是因为不完整的回滚尝试将堆栈中的 lambda 恢复到 nodejs8.10,这会导致更大的故障。如果这不是问题,我不知道我会感受到这个模糊错误的影响。

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

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'

注意 -

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

更新:

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

堆栈使用的 IAM 角色具有这些权限

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

amazon-web-services aws-cloudformation amazon-cloudfront
1个回答
5
投票

基于聊天讨论。

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

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

向角色添加该权限,解决了问题。

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

© www.soinside.com 2019 - 2024. All rights reserved.