簡體   English   中英

如何使用 Cloud Formation 使用 ACM 證書預置 CloudFront 分配

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

我正在嘗試使用 Cloud Formation 在我的 CloudFrontDistribution 中設置證書。

我的證書是通過證書管理器頒發的。 它已獲得批准,並且我已通過 CloudFront 控制台直接通過手動配置驗證該證書是否有效。

在我的 CloudFormation 模板中,我嘗試在 IamCertificateId 屬性中使用與證書關聯的IdentifierARN值:

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

但在這兩種情況下,我都會收到以下錯誤:

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

閱讀DistributionConfig 復雜類型的文檔,看起來有一個“ACMCertificateArn”屬性,但這似乎不適用於 CloudFormation。

任何幫助,將不勝感激。

(更新:截至2016年8月9日 ,AWS CloudFormation現在使用AcmCertificateArn屬性支持ACM,因此不再需要下面描述的自定義資源。)


盡管尚未更新AWS :: CloudFront :: Distribution資源以支持ACMCertificateArn屬性,但目前可以使用自定義CloudFormation資源直接使用AWS API實現所需功能,直到官方資源更新為止。

請參閱Ryan S. Brown的帖子, CloudFormation使用(免費)自定義SSL構建CDN ,其中描述了將ACM證書與CloudFront分配相關聯的Custom::CloudFrontAcmAssociation資源的實現。 該代碼可在ryansb/acm-certs-cloudformation

要使用它,您需要通過AWS Lambda函數提供CloudFormation資源的實現。 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
  }
},

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

使用lambda函數,最后添加Custom::CloudFrontAcmAssociation資源,提供分發ID,證書ARN和自定義資源lambda函數的ARN:

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

tldr:將上面的所有代碼復制到您的CloudFormation模板中,設置相應的SiteCDNAcmCertificate屬性(或使用硬編碼值編輯模板),並且您應該有自定義資源解決方法,直到Amazon更新官方CloudFront資源。

Cloudformation添加了此屬性,但未記錄。 您可以輕松使用:

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

請注意,證書必須在us-east-1區域中創建,否則將不被接受。

我有一個正確創建的證書(公鑰2048位),上傳了完整的鏈。 更具挑戰性的是,在其他AWS服務(公共ELB)中使用證書沒有問題。

我也正確地傳遞了證書ID(我也嘗試過使用ARN,但這是不正確的)。

就我而言,問題是證書是用“路徑”創建的:“/”。 在我使用“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/

我現在使用的另一種有效方法只是在沒有頒發證書的情況下創建具有默認證書的堆棧(靈感來自此帖子

看起來像

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

重要的是要注意 cloudformation 模板的字段名稱的大寫。

AcmCertificateArn不是 ACMCertificateArn

IamCertificateId不是 IAMCertificateId

作為 cloudformation 的新手,我從使用不同 CamelCase 的 CLI 查詢的 output 粘貼。 Cloudformation 會抱怨,但發現不同的情況對我來說並不是很明顯。

花了幾天時間,但在AWS支持的幫助下找到了答案。

信息:

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

使用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"
}, 

一旦我發現我添加了一個帶有ServerCertificateId的變量cloudfront.CloudFrontCertificateId並將其提供給ViewerCertificate:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM