简体   繁体   English

如何使用 Cloud Formation 使用 ACM 证书预置 CloudFront 分配

[英]How to provision a CloudFront distribution with an ACM Certificate using Cloud Formation

I am attempting to set a certificate in my CloudFrontDistribution using Cloud Formation.我正在尝试使用 Cloud Formation 在我的 CloudFrontDistribution 中设置证书。

My certificate has been issued via Certificate Manager.我的证书是通过证书管理器颁发的。 It has been approved, and I have validated that the certificate works by manual configuration directly through the CloudFront console.它已获得批准,并且我已通过 CloudFront 控制台直接通过手动配置验证该证书是否有效。

Within my CloudFormation template, I have attempted to use both the Identifier and ARN values associated with the certificate in the IamCertificateId property:在我的 CloudFormation 模板中,我尝试在 IamCertificateId 属性中使用与证书关联的IdentifierARN值:

 "ViewerCertificate": { "IamCertificateId": "********", "SslSupportMethod": "sni-only" }

But in both cases I receive the following error:但在这两种情况下,我都会收到以下错误:

 The specified SSL certificate doesn't exist, isn't valid, or doesn't include a valid certificate chain.

Reading the docs for the DistributionConfig Complex Type it looks like there is a 'ACMCertificateArn' property, but this does not seem to work via CloudFormation.阅读DistributionConfig 复杂类型的文档,看起来有一个“ACMCertificateArn”属性,但这似乎不适用于 CloudFormation。

Any help would be appreciated.任何帮助,将不胜感激。

(Update: As of Aug 9 2016 , AWS CloudFormation now supports ACM using the AcmCertificateArn property, so the custom resource described below is no longer needed.) (更新:截至2016年8月9日 ,AWS CloudFormation现在使用AcmCertificateArn属性支持ACM,因此不再需要下面描述的自定义资源。)


Although the AWS::CloudFront::Distribution resource hasn't been updated to support the ACMCertificateArn property yet, it is currently possible to use a custom CloudFormation resource to implement the functionality needed using the AWS API directly until the official resource is updated. 尽管尚未更新AWS :: CloudFront :: Distribution资源以支持ACMCertificateArn属性,但目前可以使用自定义CloudFormation资源直接使用AWS API实现所需功能,直到官方资源更新为止。

See Ryan S. Brown's post, CloudFormation To Build A CDN With (Free) Custom SSL where he describes his implementation of a Custom::CloudFrontAcmAssociation resource that associates an ACM certificate with a CloudFront distribution. 请参阅Ryan S. Brown的帖子, CloudFormation使用(免费)自定义SSL构建CDN ,其中描述了将ACM证书与CloudFront分配相关联的Custom::CloudFrontAcmAssociation资源的实现。 The code is available at ryansb/acm-certs-cloudformation . 该代码可在ryansb/acm-certs-cloudformation

To use it, you need to make the CloudFormation resource's implementation available through an AWS Lambda function. 要使用它,您需要通过AWS Lambda函数提供CloudFormation资源的实现。 Ryan's implementation is already published to a public S3 bucket, so you can reference this directly for testing purposes in your CloudFormation template like so: Ryan的实现已发布到公共S3存储桶,因此您可以在CloudFormation模板中直接引用它以进行测试,如下所示:

"AcmAssociationFunction": {
  "Type": "AWS::Lambda::Function",
  "Properties": {
    "Handler": "cloudfront_associator.handler",
    "MemorySize": 128,
    "Runtime": "python2.7",
    "Code": {
      "S3Bucket": "demos.serverlesscode.com",
      "S3Key": "acm-certificate-resource-functions.zip"
    },
    "Role": {"Fn::GetAtt": ["ExecRole", "Arn"]},
    "Timeout": 300
  }
},

The Lambda::Function resource has a dependency on an IAM service Role and associated Policy to delegate the necessary permissions to the lambda function (the ExecRole reference above), so you need to add that too: Lambda::Function资源依赖于IAM服务角色和相关策略来委派必需的权限到lambda函数(上面的ExecRole参考),因此您还需要添加它:

"ExecRolePolicies": {
  "Type": "AWS::IAM::Policy",
  "Properties": {
    "PolicyName": "ExecRolePolicy",
    "PolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": [
            "acm:*",
            "cloudfront:List*",
            "cloudfront:Get*",
            "cloudfront:UpdateDistribution"
          ],
          "Resource": [ "*" ],
          "Effect": "Allow"
        },
        {
          "Action": [ "logs:*" ],
          "Resource": "arn:aws:logs:*:*:*",
          "Effect": "Allow"
        }
      ]
    },
    "Roles": [{"Ref": "ExecRole"}]
  }
},
"ExecRole": {
  "Type": "AWS::IAM::Role",
  "Properties": {
    "AssumeRolePolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": ["sts:AssumeRole"],
          "Effect": "Allow",
          "Principal": {"Service": ["lambda.amazonaws.com"]}
        }
      ]
    }
  }
},

With the lambda function in place, finally add the Custom::CloudFrontAcmAssociation resource, providing the distribution ID, certificate ARN, and the custom resource lambda function's ARN: 使用lambda函数,最后添加Custom::CloudFrontAcmAssociation资源,提供分发ID,证书ARN和自定义资源lambda函数的ARN:

"DistributionCertificateSetting": {
  "Type": "Custom::CloudFrontAcmAssociation",
  "Properties": {
    "DistributionId": {
      "Ref": "SiteCDN"
    },
    "CertificateArn": {
      "Ref": "AcmCertificate"
    },
    "ServiceToken": {
      "Fn::GetAtt": [
        "AcmAssociationFunction",
        "Arn"
      ]
    }
  }
},

tldr: copy all the code above into your CloudFormation template, set the appropriate SiteCDN and AcmCertificate properties (or edit the template with hard-coded values), and you should have a custom resource workaround until Amazon updates the official CloudFront resource. tldr:将上面的所有代码复制到您的CloudFormation模板中,设置相应的SiteCDNAcmCertificate属性(或使用硬编码值编辑模板),并且您应该有自定义资源解决方法,直到Amazon更新官方CloudFront资源。

Cloudformation added this property but it is not documented. Cloudformation添加了此属性,但未记录。 You can use like this easily: 您可以轻松使用:

"ViewerCertificate": {
            "SslSupportMethod": "sni-only",
            "AcmCertificateArn": "CERTIFICATE_ARN"
}

Be aware that the certificate must be created in us-east-1 region, if not it won't be accepted. 请注意,证书必须在us-east-1区域中创建,否则将不被接受。

I had a properly created certificate (public key 2048 bits), uploaded with the full chain. 我有一个正确创建的证书(公钥2048位),上传了完整的链。 What was more challenging was the certificate was being used without problem in other AWS services (public ELB). 更具挑战性的是,在其他AWS服务(公共ELB)中使用证书没有问题。

I was also passing the certificate Id (I had also tried with ARN but that's incorrect) correctly. 我也正确地传递了证书ID(我也尝试过使用ARN,但这是不正确的)。

In my case, the problem was the certificate had been created with a "path": "/". 就我而言,问题是证书是用“路径”创建的:“/”。 After I uploaded a new certificate (with different name) with "Path": "/cloudfront/", everything worked without problem. 在我使用“Path”:“/ cloudfront /”上传新证书(具有不同名称)之后,一切都正常运行。

  aws iam upload-server-certificate \
    --server-certificate-name cert_cf \
    --certificate-body file://cert.crt \
    --private-key file://cert.key \
    --certificate-chain file://chain.pem \
    --path /cloudfront/

Another valid approach I now use just creates the stack with the default certificate as long as the certificate is not issued (Inspired by this post ) 我现在使用的另一种有效方法只是在没有颁发证书的情况下创建具有默认证书的堆栈(灵感来自此帖子

It looks like 看起来像

"Conditions": {
    "HasAcmCertificate": {
        "Fn::Equals": [
            {
                "Ref": "CloudfrontCertificateArn"
            },
            "NOT_ISSUED"
        ]
    }
},

...

"Cloudfront": {
    "Properties": {
        "DistributionConfig": {

            ...

            "ViewerCertificate": {
                "AcmCertificateArn": {
                    "Fn::If": [
                        "HasAcmCertificate",
                        {
                            "Ref": "AWS::NoValue"
                        },
                        {
                            "Ref": "CloudfrontCertificateArn"
                        }
                    ]
                },
                "CloudFrontDefaultCertificate": {
                    "Fn::If": [
                        "HasAcmCertificate",
                        true,
                        {
                            "Ref": "AWS::NoValue"
                        }
                    ]
                },
                "SslSupportMethod": {
                    "Fn::If": [
                        "HasAcmCertificate",
                        {
                            "Ref": "AWS::NoValue"
                        },
                        "sni-only"
                    ]
                }
            }
        }
    },
    "Type": "AWS::CloudFront::Distribution"
},

Important to note capitalization of the field name for the cloudformation template.重要的是要注意 cloudformation 模板的字段名称的大写。

AcmCertificateArn not ACMCertificateArn AcmCertificateArn不是 ACMCertificateArn

IamCertificateId not IAMCertificateId IamCertificateId不是 IAMCertificateId

As a newbie to cloudformation I was pasting from the output of CLI queries which use different CamelCase.作为 cloudformation 的新手,我从使用不同 CamelCase 的 CLI 查询的 output 粘贴。 Cloudformation would complain but spotting the different case was not immediately obvious to me. Cloudformation 会抱怨,但发现不同的情况对我来说并不是很明显。

Took a few days but found the answer with some help from AWS support. 花了几天时间,但在AWS支持的帮助下找到了答案。

The information for: 信息:

"ViewerCertificate" : {
  "IamCertificateId" : "********",
  "SslSupportMethod": "sni-only"
}

is found using the CLI "aws iam list-server-certificates": 使用CLI“aws iam list-server-certificates”找到:

{
    "ServerCertificateId": "ASCAXXXXXXXXXXXXXX", 
    "ServerCertificateName": "devops.XXXXXXX.com", 
    "Expiration": "2017-03-10T15:00:33Z", 
    "Path": "/cloudfront/", 
    "Arn": "arn:aws:iam::XXXXXXXXXXX:server-certificate/cloudfront/devops.XXXXXXXXXXX.com", 
    "UploadDate": "2016-03-14T16:13:59Z"
}, 

Once I found that I added a variable cloudfront.CloudFrontCertificateId with the ServerCertificateId and fed it into the ViewerCertificate: 一旦我发现我添加了一个带有ServerCertificateId的变量cloudfront.CloudFrontCertificateId并将其提供给ViewerCertificate:

"ViewerCertificate" : {
  "IamCertificateId" : {{ cloudfront.CloudFrontCertificateId }},
  "SslSupportMethod": "sni-only"
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 云形成模板在 dynamodb 提供中使用 If 条件提供两个 GSI NonKeyAttributes - cloud formation template using If condition provision two GSI NonKeyAttributes in dynamodb provision ACM请求的公共SSL证书未出现在CloudFront中 - ACM Requested Public SSL certificate not appearing in CloudFront 如何使用在证书管理器中创建的相同 SSL 证书创建另一个云端分发 - How to create another cloudfront distribution using same SSL certificates created in certificate manager 对CloudFront分配中的不同域使用不同的SSL证书? - Using a different SSL certificate for different domains in CloudFront distribution? 如何使用 Paws 在 CloudFront 上创建分配 - How to create a distribution on CloudFront using Paws ACM 在另一个账户中为 Cloud front 生成证书 - Certificate generation by ACM for Cloud front in another account 云层如何运作 - How Cloud Formation Works 如何在不使用ACM(AWS证书管理器)的情况下获取SSL证书的ARN(亚马逊资源名称)? - How to get the ARN (Amazon Resource Name) of SSL certificate without using ACM (AWS Certificate Manager)? 使用 python 在 AWS ACM 中导入证书 - Import certificate in AWS ACM using python 使用 Cloudflare 的 AWS ACM 证书链 - Certificate chain for AWS ACM using Cloudflare
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM