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

Cannot use the output of the inner (child ) template in the parent template in cloudformation

我正在尝试在另一个中使用 cloudformation 堆栈的输出。我看了一些examoles,例如 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 的名称。这是我的主要模板代码:

{
"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 存储桶的名称。我该怎么做?

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

Export (optional)

The name of the resource output to be exported for a cross-stack reference.

Note

The following restrictions apply to cross-stack references:

  • For each AWS account, Export names must be unique within a region.
  • You can't create cross-stack references across regions.
  • You can use the intrinsic function Fn::ImportValue to import only values that have been exported within the same region.

  • For outputs, the value of the Name property of an Export can't use Ref or GetAtt functions that depend on a resource. Similarly, the ImportValue function can't include Ref or GetAtt functions that depend on a resource.

  • You can't delete a stack if another stack references one of its outputs.

  • You can't modify or remove an output value that is referenced by another stack.

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

所以添加导出 属性:

"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.

我已经在 CFN 课程论坛上回复了

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

您不需要使用 Export/Import 值,因为您正在使用嵌套堆栈。