属性值参数必须是具有String(或简单类型)属性的对象

时间:2019-12-02 17:02:55

标签: amazon-web-services amazon-ec2 yaml

我试图通过从另一个嵌套堆栈输出中填充值来将参数传递给其中一个嵌套堆栈。

而且我不希望有任何交叉引用(除非无法解决)

这个想法很简单。

RootStack

-NstdStackVPC
-NstdStackSG
-NstdStackEC2

问题出在创建EC2时的最后一个嵌套堆栈上。 如果我直接在根堆栈中创建资源,则EC2会被创建

Description: RootStack
Parameters:
 MyKeyName:
  Type: AWS::EC2::KeyPair::KeyName
  Default: my-test-key
 EC2ImageId:
  Type: AWS::EC2::Image::Id
  Default: ami-0dxxxxa

Resources:
 NstdStackVPC ......
 NstdStackSG ......

 EC2Host: 
  Type: AWS::EC2::Instance
  Properties:
   SubnetId: !GetAtt NstdStackVPC.Outputs.VPCPubSubnet
   ImageId: !Ref EC2ImageId
   InstanceType: t2.micro
   KeyName: !Ref MyKeyName
   SecurityGroupIds: 
   - !GetAtt NstdStackSG.Outputs.SecGrp4EC2Host

但是如果我尝试将EC2创建为嵌套堆栈

AWSTemplateFormatVersion: '2010-09-09'
Description: NstdStackEC2.
Parameters:
 myNstdKeyName:
  Type: AWS::EC2::KeyPair::KeyName
 myNstdImageId:
  Type: AWS::EC2::Image::Id
 myNstdSecGrp:
  Type: AWS::EC2::SecurityGroup::Id
 myNstdEC2HostSubnet:
  Type: AWS::EC2::Subnet::Id

Resources:
 EC2Host: 
  Type: AWS::EC2::Instance
  Properties:
   SubnetId: !Ref myNstdEC2HostSubnet
   ImageId: !Ref myNstdImageId
   InstanceType: t2.micro
   KeyName: !Ref myNstdKeyName
   SecurityGroupIds:
    - Ref myNstdSecGrp  

通过如下更改根堆栈

AWSTemplateFormatVersion: '2010-09-09'
Description: RootStack
Parameters:
 MyKeyName:
  Type: AWS::EC2::KeyPair::KeyName
  Default: my-test-key
 EC2ImageId:
  Type: AWS::EC2::Image::Id
  Default: ami-0dxxxxa

Resources:
 NstdStackVPC ......
 NstdStackSG ......
 NstdStackEC2:
  Type: AWS::CloudFormation::Stack
  Properties:
   TemplateURL: https://bkt.s3.eu-central-1.amazonaws.com/NstdEC2Host.yml
   Parameters:
    myNstdKeyName: !Ref MyKeyName
    myNstdImageId: !Ref EC2ImageId
    myNstdSecGrp: !GetAtt NstdStackSG.Outputs.SecGrp4BasHost
    myNstdEC2HostSubnet: !GetAtt NstdStackVPC.Outputs.VPCPubSubnet   

它给了我以下错误: 属性值参数必须是具有String(或简单类型)属性的对象

试图删除所有参数以一一尝试。但这一切都失败了。 即使对于直接从根堆栈直接引用的参数,即MyKeyName,EC2ImageId

2 个答案:

答案 0 :(得分:2)

我遇到了完全相同的错误消息,遇到了类似的问题和解决方案。我来到这里,由于问题略有不同,这个问题帮助我找到了解决方案。所以,不是试图劫持这个问题,只是希望提供我认为对下一个访问者有用的内容。

我嵌套了一个与 this one 和 OP 示例非常相似的集群模板。将子网作为字符串列表传递(我相信 List 也可以)。

Subnets:
  Description: Subnets of the of the cluster availaibility zone
  Type: CommaDelimitedList
  Default: subnet-0d..de,subnet-0e..7a,subnet-0b..24

我使用上述参数调用部分子模板如下。

ECS:
  Type: AWS::CloudFormation::Stack
  Properties:
    TemplateURL: https://xx.amazonaws.com/yy/zz.yaml
    Parameters:
      SecurityGroups: !Join [",", [!GetAtt SecurityGroups.Outputs.ECSHostSecurityGroup]]
      Subnets: !Join [",", !Ref Subnets]

因此,在上面的示例中,SecurityGroup 从 SecurityGroup 嵌套模板的输出中连接到一个列表中,但子网只是通过逗号分隔的参数连接在一起。如果您想了解更多信息,有一个 knowledge-center article too。 TA OP

答案 1 :(得分:0)

好吧,我终于自己解决了这个问题。

在我的NstdStackSG输出部分中,我指的是对象本身。 这就是问题所在。

AWSTemplateFormatVersion: 2010-09-09
Description: Security group nested stack
Resources:
 MySecGrp
  Type: ....
  .....
  ....
Outputs:
 MyOtptSecGrp:
#This one is working for me.
  Value: !GetAtt MySecGrp.GroupId
#previously i was assigning the following value
  #Value: !Re MySecGrp

现在在RootStack中

AWSTemplateFormatVersion: '2010-09-09'
Description: RootStack
Parameters:
 MyKeyName:
  Type: AWS::EC2::KeyPair::KeyName
  Default: my-test-key
 EC2ImageId:
  Type: AWS::EC2::Image::Id
  Default: ami-0dxxxxa
Resources:
 NstdStackVPC ......
 NstdStackSG ......
 NstdStackEC2:
  Type: AWS::CloudFormation::Stack
  Properties:
   TemplateURL: https://bkt.s3.eu-central-1.amazonaws.com/NstdEC2Host.yml
   Parameters:
    myNstdKeyName: !Ref MyKeyName
    myNstdImageId: !Ref EC2ImageId
    myNstdSecGrp: !GetAtt NstdStackSG.Outputs.SecGrp4BasHost
    myNstdEC2HostSubnet: !GetAtt NstdStackVPC.Outputs.VPCPubSubnet    

在我的nestedEC2Stack中

AWSTemplateFormatVersion: 2010-09-09
Description: NstdStackEC2

Parameters:
 myNstdSecGrp:
  Type: AWS::EC2::SecurityGroup::Id
 myNstdEC2HostSubnet:
  Type: AWS::EC2::Subnet::Id
 myNstdKeyName:
  Type: AWS::EC2::KeyPair::KeyName
 myNstdImageId:
  Type: AWS::EC2::Image::Id

Resources:

 EC2Host: 
  Type: AWS::EC2::Instance
  Properties:
   SubnetId: !Ref myNstdEC2HostSubnet
   ImageId: !Ref myNstdImageId
   InstanceType: t2.micro
   KeyName: !Ref myNstdKeyName
   SecurityGroupIds:
    - !Ref myNstdSecGrp

希望这会有所帮助。 (如果没有解决,那么至少要指出正确的方向)