CDNをS3バケットに依存させる必要があります。ただし、新しいバケットを作成するのではなく、既存のバケットを使用するようにします。
これが私が試しているサンプルコードです:
"Parameters" : {
"UseExistingBucket" : {
"Description" : "Yes/No",
"Default" : "yes",
"Type" : "String",
"AllowedValues" : [ "yes", "no" ]
}
},
"Conditions" : {
"CreateS3Resources" : {"Fn::Equals" : [{"Ref" : "UseExistingBucket"}, "no"]}
},
"Resources" : {
"StaticBucket" : {
"Type" : "AWS::S3::Bucket",
"Condition" : "CreateS3Resources",
"Properties" : {
"BucketName" : { "Fn::Join": [ "-", [ "app", { "Ref": "EnvType" }, "static" ] ] }
},
"DeletionPolicy": "Retain"
},
"MyStaticDistribution": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"Origins": [
{
"DomainName": {
"Fn::If" : [
"CreateS3Resources",
{ "Fn::Join": [ "-", [ "app", { "Ref": "EnvType" }, "static" ] ] },
{"Fn::GetAtt": [ "StaticBucket", "DomainName" ] }
]
},
"Id": "S3Origin",
}
]
}
},
"DependsOn": [{
"Fn::If" : [
"CreateS3Resources",
{ "Fn::Join": [ "-", [ "app", { "Ref": "EnvType" }, "static" ] ] },
""
]
}]
}
}
必要に応じて、詳細を教えてください(少なくとも、stackoverflowでは詳細が必要ですが、-Pは指定していません)。
これを行うには、条件付きFn:GetAtt
でラップされたFn:If
を使用します。 Fn:GetAttを使用すると、依存関係が暗黙指定されます。したがって、DeformsOnを使用している場合と同様に、CloudFormationは関数に到達すると自動的に待機します。
例
以下のコードスニペットは、まだ作成されていないネストされたスタックの名前を条件付きで取得することによってこれを示していますが、条件UseNestedStackがtrueに設定されている場合にのみ取得されます。 UseNestedStackがfalseの場合、待機せず、代わりにローカル変数名を取得します。
{
"Fn::If": ["UseNestedStack", {
"Fn::GetAtt": ["NestedStack", "Outputs.Name"]
}, {
"Ref": "LocalName"
}]
どうやってこれを知るのですか?(別の例)
残念ながら、これを公式に述べた公式のドキュメントはありませんが、このようにするように私に言ったのはAWSでした。彼らのコード例では、注文が重要なときにFn:GetAttを使用していることがわかります。私はこれを何度も試しましたが、いつでもうまくいきます。簡単なスタックで試してみてください。これは、私が微調整して自分で使用したAWSラムダの例からのいくつかの疑似証明です。以下のスタックは、リソースAMI情報の後にAMI関数が作成された場合は機能しない可能性があります。AMI情報はAMI関数の出力を必要とするため、AWSはFn:GetAttを使用してそれらをチェーンしました。このスクロールを一番下までスクロールしてリソースAMIInfoを見ると、fn:Gettを介してAMIFunctionを参照していることがわかります。 CloudFormationはこれを確認し、AMIFunctionに戻って最初に作成します。
"AMIInfoFunction": {
"DependsOn":"SourceStack",
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": { "Ref": "DeploymentBucket" },
"S3Key": {"Fn::Join": [
"",
[
{
"Ref": "ApplicationName"
},
"/amilookup.Zip"
]
]}
},
"Handler": "amilookup.handler",
"Runtime": "nodejs",
"Timeout": "30",
"Role": { "Fn::GetAtt" : ["LambdaExecutionRole", "Arn"] },
"VpcConfig": {
"SecurityGroupIds": [ {"Ref": "InstanceSecurityGroup"}],
"SubnetIds": [ {"Ref":"PrivateSubnetA"},{"Ref":"PrivateSubnetB"} ]
}
}
},
"AMIInfo": {
"Type": "Custom::AMIInfo",
"Properties": {
"ServiceToken": { "Fn::GetAtt" : ["AMIInfoFunction", "Arn"] },
"StackName": { "Ref":"SourceStack" }
}
}
テンプレートでは、StaticBucketリソースへの参照が既にあるため、MyStaticDistributionリソースにDependsOn属性を追加する必要はありません。
これは、 Optimize AWS CloudFormation Templates blog post の Specifying Dependencies セクションに記載されています: https://aws.Amazon .com/blogs/devops/optimize-aws-cloudformation-templates /
When you need CloudFormation to wait to provision one resource until another one has been provisioned, you can use the DependsOn attribute.
You can also introduce references between elements by using either the { "Ref": "MyResource" } or the { "Fn::GetAtt" : [ "MyResource" , "MyAttribute" ] } functions. When you use one of these functions, CloudFormation behaves as if you’ve added a DependsOn attribute to the resource.
Yamlユーザーの場合は、次も使用できます。
Conditions:
CreateConfigRecorder: !Equals [ !Ref ConfigRecorderExists, 'false' ]
Resource:
#my 1st AWS Resource
ConfigRecorder:
Condition: CreateConfigRecorder
Type: AWS::Config::ConfigurationRecorder
*more codes below*
#added, since DependsOn: !If is not possible, trigger by WaitCondition if CreateConfigRecorder is true
#Hacks: https://garbe.io/blog/2017/07/17/cloudformation-hacks/
ConfigRecorderWaitHandle:
Condition: CreateConfigRecorder
DependsOn: ConfigRecorder
Type: "AWS::CloudFormation::WaitConditionHandle"
#added, since DependsOn: !If is not possible, trigger by WaitCondition if CreateConfigRecorder is false
WaitHandle:
Type: "AWS::CloudFormation::WaitConditionHandle"
#added, since DependsOn: !If is not possible
WaitCondition:
Type: "AWS::CloudFormation::WaitCondition"
Properties:
Handle: !If [CreateConfigRecorder, !Ref ConfigRecorderWaitHandle, !Ref WaitHandle]
Timeout: "1"
Count: 0
#my 2nd AWS Resource that requires DependsOn Attribute
AWSConfigRule:
Type: AWS::Config::ConfigRule
DependsOn: WaitCondition #added, since DependsOn: !If is not possible
*more codes below*
基本的に、CFNを実行する前に、1番目のリソースが存在しない場合、2番目のリソースにはDependsOn属性しかありません。私はこれを手に入れました: https://garbe.io/blog/2017/07/17/cloudformation-hacks/
私は同じことを戦っています。エラーは:
ValidateTemplate操作の呼び出し時にクライアントエラー(ValidationError)が発生しました:テンプレート形式エラー:DependsOnは文字列または文字列のリストでなければなりません。
DependsOn内に条件を置くことは可能ではないようです。
それを表現する他の方法を探し始めました。多分依存するコードを2つの異なる子テンプレートに配置します。条件を外部で検出し、適切なネストされたテンプレート名を親テンプレートパラメータに渡します。したがって、DependsOnは、依存するテンプレートとして渡したパラメーターを参照します。
過度に歪んだロジックのようです。
より良い方法でなければなりません。