无法在cloudformation中使用父模板中内部(子)模板的输出

时间:2017-07-02 18:36:11

标签: amazon-web-services amazon-cloudformation

我正在尝试在另一个中使用cloudformation堆栈的输出。我看了一些例如 https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/walkthrough-crossstackref.html

但它非常混乱,我无法在我的例子中使它工作:

这就是我所拥有的:我有一个beanstalk.json模板,我输出我在资源部分创建的sampleEnvironment:

{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
    "sampleApplication": {
        "Type": "AWS::ElasticBeanstalk::Application",
        "Properties": {
            "Description": "AWS Elastic Beanstalk Sample Application",
            "ApplicationName": "app-name-test"
        }
    },
    "sampleApplicationVersion": {
        "Type": "AWS::ElasticBeanstalk::ApplicationVersion",
        "Properties": {
            "ApplicationName": {
                "Ref": "sampleApplication"
            },
            "Description": "AWS ElasticBeanstalk Sample Application Version",
            "SourceBundle": {
                "S3Bucket": "test-war",
                "S3Key": "deployment.war"
            }
        }
    },
    "sampleConfigurationTemplate": {
        "Type": "AWS::ElasticBeanstalk::ConfigurationTemplate",
        "Properties": {
            "ApplicationName": {
                "Ref": "sampleApplication"
            },
            "Description": "AWS ElasticBeanstalk Sample Configuration Template",
            "OptionSettings": [{
                    "Namespace": "aws:autoscaling:asg",
                    "OptionName": "MinSize",
                    "Value": "2"
                },
                {
                    "Namespace": "aws:autoscaling:asg",
                    "OptionName": "MaxSize",
                    "Value": "3"
                },
                {
                    "Namespace": "aws:elasticbeanstalk:environment",
                    "OptionName": "EnvironmentType",
                    "Value": "LoadBalanced"
                }
            ],
            "SolutionStackName": "64bit Amazon Linux 2017.03 v2.6.1 running Tomcat 8 Java 8"
        }
    },
    "sampleEnvironment": {
        "Type": "AWS::ElasticBeanstalk::Environment",
        "Properties": {
            "ApplicationName": {
                "Ref": "sampleApplication"
            },
            "Description": "AWS ElasticBeanstalk Sample Environment",
            "TemplateName": {
                "Ref": "sampleConfigurationTemplate"
            },
            "VersionLabel": {
                "Ref": "sampleApplicationVersion"
            },
            "EnvironmentName": "test-dep-env-name"
        }
    }
},
 "Outputs": {
    "applicationName11": {
       "Description": "The application chosen by user is :",
       "Value": {
        "Ref": "sampleEnvironment"
      },
   "Export" : {
    "Name" : {"Ref": "sampleEnvironment"} 
    }
 }
}

现在我的问题开始了。我需要引用在beanstalk.json中创建的sampleEnvironment的名称,并将其分配给主模板中使用beanstalk.json模板的资源部分中的s3的名称。这是我的主要tempalte代码:

{
"Parameters": {
    "appName1": {
        "Description": "enter the app name",
        "Type": "String",
        "Default": "bn-test-jun"
    },
    "appEnv1": {
        "Description": "enter the app name",
        "Type": "String",
        "Default": "bn-test-jun"
    }
},
"Resources": {
    "CodeDeployEC2InstancesStack": {
        "Type": "AWS::CloudFormation::Stack",
        "Properties": {
            "TemplateURL": "https://s3.amazonaws.com/url...../beanstalk.json",
            "TimeoutInMinutes": "60"
        }
    },
    "myS3": {
        "Type": "AWS::S3::Bucket",
        "Properties": {
            "AccessControl": "PublicRead",
            "BucketName": "name of the environment returned as an output sth like Outputs.EnvironmentName"
        }
    }
}
 ,
 "Outputs":{
  "app":{
  "Description": "The application chosen by user is :",
     "Value": {
             "Fn::ImportValue" : "sampleEnvironment" 
     }
   }
 }
  }

现在你看到在bucketName部分我被卡住了。我需要将在beanstalk.json中创建的环境的名称分配给将要创建的s3存储桶的名称。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

我在CFN课程论坛上回复了

https://acloud.guru/forums/aws-advanced-cloudformation/discussion/-KoAxjlT_ZtSAdrlg1lp/cannot_use_the_output_of_the_i

您不需要使用导出/导入值,因为您正在使用嵌套堆栈。

答案 1 :(得分:0)

导出参数需要Export property才能被其他堆栈访问:

  

导出(可选)

     
    

要为跨堆栈引用导出的资源输出的名称。

         
      

注意

             
        

以下限制适用于跨堆栈引用:

                 
            
  • 对于每个AWS账户,导出名称在区域内必须是唯一的。
  •         
  • 您无法跨地区创建跨堆栈引用。
  •         
  • 您可以使用内在函数Fn :: ImportValue仅导入已在同一区域内导出的值。

  •         
  • 对于输出,Export的Name属性的值不能使用依赖于资源的Ref或GetAtt函数。同样,ImportValue函数不能包含依赖于资源的Ref或GetAtt函数。

  •         
  • 如果另一个堆栈引用其中一个输出,则无法删除堆栈。

  •         
  • 您无法修改或删除另一个堆栈引用的输出值。

  •         
      
    
         

您可以使用内部函数来自定义导出的Name值。以下示例使用 Fn :: Join函数

  

所以添加 Export 属性:

"Outputs": {
  "applicationName11": {
    "Description": "The application chosen by user is :",
    "Value": {
        "Ref": "sampleEnvironment"
    },
    "Export" : {
      "Name" : {
        "Fn::Join" : [ "-", [ { "Ref" : "AWS::StackName" }, {"Ref": "something"} ] ]
        }
     }
  }
}

然后您可以通过 Fn :: ImportValue 在必要时导入它。 AWS有一个good example