2016-01-05 25 views
10

Yapmam gereken görev, CDN'nin S3 paketine bağlı olması gerektiğidir, ancak yeni bir tane oluşturmak yerine varolan paketi de kullanabiliriz. İşte CloudFormation, Geçerli Koşulları Uygula

i ile savaşıyorum örnek kod: Gerekirse

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

bana daha fazla ayrıntı önermek Lütfen

cevap

0

(en az stackoverflow daha fazla ayrıntı, ancak herhangi :-P belirterek değildir istiyor etmez) Ben de aynı şeyle savaşıyorum. hatadır:

A client error (ValidationError) occurred when calling the ValidateTemplate operation: Template format error: DependsOn must be a string or list of strings.

bir bağlı olduğu ifade içinde koşullu koymak mümkün görünmüyor.

Bunu ifade etmenin başka yollarını aramaya başladım. Belki de bağımlı kodu 2 farklı alt şablona yerleştiririz. Durumu harici olarak algıla ve uygun iç içe şablon adını ana şablon parametresine ilet. Bu nedenle DependsOn, değiştirdiğim parametreyi bağımlı şablon olarak görüyor.

Aşırı çarpık mantık gibi görünüyor.

Daha iyi bir yol olmalı.

7

Bunu, koşullu bir Fn:If sarılmış Fn:GetAtt kullanarak yapabilirsiniz. Fn'yi kullanma: GetAtt, bağımlılığı anlamına gelir; bu nedenle, CloudFormation, bir DependsOn kullanıyormuşsunuz gibi, o işleve ulaştığında otomatik olarak bekler.

Örnek

kod parçacığı aşağıda şartlı henüz oluşturulmadı iç içe geçmiş bir yığın adını alarak bu gösteriyor ama durum UseNestedStack true değerine ayarlanırsa, yalnızca yapar. UseNestedStack yanlışsa, beklemez ve bunun yerine bir yerel değişken adı alır.

{ 
"Fn::If": ["UseNestedStack", { 
    "Fn::GetAtt": ["NestedStack", "Outputs.Name"] 
}, { 
    "Ref": "LocalName" 
}] 

Bunu nasıl bilebilirim? (Bir başka örnek)

Maalesef bunu resmi olarak belirten resmi bir belge yoktur, ancak bu şekilde yapmamı söyleyen AWS'tir ve kod örneklerinde siparişte Fn: GetAtt kullandıklarını görebilirsiniz. Bunu defalarca denedim ve her seferinde çalışıyor. Basit bir yığında deneyin. İşte AWS lambda örneğinden biraz daha sahte ispat ettim ve kendimi kullandım. AMI işlevi, kaynak AMI bilgisi, AMI Bilgisi AMI işlevinin çıktısı alındıktan sonra oluşturulduysa, aşağıdaki yığın işe yaramayabilir; dolayısıyla AWS, bunları Fn: GetAtt kullanarak birlikte zincirlemiştir. Bu kaydırmayı aşağıdan görmek ve kaynak AMIInfo'ya bakmak için AMFunction'u fn: Gett. CloudFormation bunu görür ve ilk önce oluşturmak için AMIFTION'a geri döner. Şablonunuzda

"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" } 
    } 
} 
+0

yerde var dokümantasyon mı:

Bu Optimize AWS CloudFormation Şablonları blog yayınında ait Belirleme bağımlılıklar bölümünde belgelenmiştir ilerletmeden önce diğer kaynağın bitmesini bekleyin? – doeiqts

+2

@doeiqts Güzel soru. Ne yazık ki bunu belgelediğini görmedim, ancak bunun AWS örneklerinde kullanılmasından doğru olduğuna eminim, bunun birçok kez çalıştığını gördüm ve AWS mühendislerinden bu şekilde yapmamı emretti. AWS'den bu şekilde yaratmayı erteledikleri bir lambda örneği ekledim. Ama evet bazı resmi belgeler daha temiz olurdu. –

0

zaten StaticBucket kaynağın bir başvuru olması gibi MyStaticDistribution kaynağına bağlı olduğu ifade öznitelik eklemek gerekmez.O GetAtt otomatik olacak diyor 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.