web-dev-qa-db-ja.com

クラウド形成を使用してACM証明書でCloudFrontディストリビューションをプロビジョニングする方法

クラウドフォーメーションを使用してCloudFrontDistributionに証明書を設定しようとしています。

証明書は、証明書マネージャーを介して発行されました。承認され、CloudFrontコンソールから直接手動で構成することで証明書が機能することを検証しました。

CloudFormationテンプレート内で、Identifier[〜#〜] arn [〜#の両方を使用しようとしました〜]IamCertificateIdプロパティの証明書に関連付けられた値:

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

しかし、どちらの場合でも、次のエラーが表示されます。

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

DistributionConfig Complex Type のドキュメントを読むと、「ACMCertificateArn」プロパティがあるように見えますが、これはCloudFormationを介して機能していないようです。

任意の助けいただければ幸いです。

16
Toby Hede

Cloudformationがこのプロパティを追加しましたが、ドキュメント化されていません。このように簡単に使用できます:

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

証明書は、受け入れられない場合は、us-east-1リージョンで作成する必要があることに注意してください。

12

(更新: 2016年8月9日 の時点で、AWS CloudFormationは AcmCertificateArn プロパティを使用してACMをサポートするようになったため、以下で説明するカスタムリソースは不要になりました。)


AWS :: CloudFront :: Distributionリソースは、ACMCertificateArnプロパティをサポートするようにまだ更新されていませんが、現在、 カスタムCloudFormationリソース を使用して、AWSAPIを使用して必要な機能を直接実装することができます。公式リソースが更新されます。

Ryan S. Brownの投稿 CloudFormation To Build A CDN With(Free)Custom SSL を参照してください。ここでは、ACM証明書をCloudFrontディストリビューションに関連付けるCustom::CloudFrontAcmAssociationリソースの実装について説明しています。コードは ryansb/acm-certs-cloudformation で入手できます。

これを使用するには、CloudFormationリソースの実装をAWSLambda関数を介して利用できるようにする必要があります。 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サービスの役割と関連するポリシーに依存しており、ラムダ関数(上記の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"]}
        }
      ]
    }
  }
},

ラムダ関数を配置したら、最後にCustom::CloudFrontAcmAssociationリソースを追加し、配布ID、証明書ARN、カスタムリソースのラムダ関数のARNを指定します。

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

tldr:上記のすべてのコードをCloudFormationテンプレートにコピーし、適切なSiteCDNプロパティとAcmCertificateプロパティを設定(またはハードコードされた値でテンプレートを編集)し、カスタムリソースの回避策をAmazonが公式のCloudFrontリソースを更新します。

14
wjordan

適切に作成された証明書(公開キー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/
2
Gonfva

私が現在使用している別の有効なアプローチは、証明書が発行されない限り、デフォルトの証明書でスタックを作成するだけです(Inspired by this post

のように見えます

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