AWS Fn::ImportValue !Sub not accepting value - amazon-web-services

I have a cloudformation script that configures a VPC and in the Outputs section it exports a few values - one is the Zone B AZ:
Parameters:
PublicAvailabilityZoneB:
Type: String
Default: us-east-1b
Outputs:
PublicAvailabilityZoneB:
Description: Pubic Subnet B Availability Zone
Value: !Ref PublicAvailabilityZoneB
Export:
Name: !Sub "${AWS::StackName}-${OwnerID}-${PublicAvailabilityZoneB}-PublicSubnetB-AZ"
In the console this is in the Outputs section:
PublicAvailabilityZoneB us-east-2b Pubic Subnet B Availability Zone Stack-02-Schwartz-us-east-2b-PublicSubnetB-AZ
I have a second CFN script that instantiates EC2 instances.
Parameters:
PublicAvailabilityZoneB:
Type: String
Default: us-east-1b
NetworkStackParameter:
Description: Parent stack
Type: String
Default: Stack-02
OwnerID:
Type: String
Default: Schwartz
Resources:
BastionInstance:
Type: 'AWS::EC2::Instance'
DependsOn:
- BastionInterface
Properties:
ImageId: !Ref LinuxAmi
InstanceType: c4.large
AvailabilityZone:
Fn::ImportValue: !Sub ${NetworkStackParameter}-${OwnerID}-${PublicAvailabilityZoneB}-PublicSubnetB-AZ
I am receiving this error when I run the second CFN script:
No export named ${NetworkStackParameter}-${OwnerID}-${PublicAvailabilityZoneB}-PublicSubnetB-AZ found.
What am I missing? I have triple checked the CFN script. Thanks.

Ugh, easy mistake. It should have had quotes
Fn::ImportValue: !Sub "${NetworkStackParameter}-${OwnerID}-${PublicAvailabilityZoneB}-PublicSubnetB-AZ"

Related

value of property security group must be of type list of string

Parameters:
KeyName:
Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
Type: 'AWS::EC2::KeyPair::KeyName'
ConstraintDescription: must be the name of an existing EC2 KeyPair.
MySubnet:
Description: My subnet from my VPC
Type: 'AWS::EC2::Subnet::Id'
Default: subnet-YYYYYYYY
MySG:
Description: My Security Group from my VPC
Type: 'AWS::EC2::SecurityGroup::GroupName'
Default: SG-YYYYYYYY
Resources:
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-09e67e426f25ce0d7
SecurityGroups: !Ref MySG
SubnetId: !Ref MySubnet
KeyName: !Ref KeyName
I have this above cloudformation template code which returns "Value of property SecurityGroups must be of type List of String", my vpc and security groups are simplified in a different cloudformation template, and i want to launch an ec2 in a specific Security group.
SecurityGroups must be a list of string, as the error says. So the correct template would be:
Resources:
Ec2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-09e67e426f25ce0d7
SecurityGroups:
- !Ref MySG
SubnetId: !Ref MySubnet
KeyName: !Ref KeyName

Cloudformation Split & ImportValue

I have 2 stacks in CloudFormation. One is creating a vpc with a couple of subnets which are exported in order to be used in other stacks. The idea is to have those subnets to be used in other stacks.
The vpc stack exports the values properly but I am unable to Import them in the second stack because it uses a list of strings.
Stack 1:
PrivateSubnets:
Description: "A list of the public subnets"
Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]]
Export:
Name: !Sub "${StagingArea}-PrivateSubnets"
PublicSubnet1:
Description: "Reference to the publi subnet in the 1st Availability Zone"
Value: !Ref PublicSubnet1
PublicSubnet2:
Description: "A reference to the public subnet in the 2nd Availability Zone"
Value: !Ref PublicSubnet2
PrivateSubnet1:
Description: "A reference to the private subnet in the 1st Availability Zone"
Value: !Ref PrivateSubnet1
Export:
Name: !Sub "${StagingArea}-PrivateSubnet1"
PrivateSubnet2:
Description: "A reference to the private subnet in the 2nd Availability Zone"
Value: !Ref PrivateSubnet2
Export:
Name: !Sub "${StagingArea}-PrivateSubnet2"
When I try to ImportValue into my second stack it does not work. Stack 2 below:
DbSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: !Sub "${StagingArea} RDS DB Subnet Group"
SubnetIds:
- !ImportValue 'Fn::Sub': '{$StagingArea}-PrivateSubnet1'
- !ImportValue 'Fn::Sub': '{$StagingArea}-PrivateSubnet2'
Is it possible to get the values exported from the first stack into the second stack? I have tried various options but none of them seem to be working.
Sub is incorrect (wrong use of $) and its better to follow the docs and have the statement in two lines:
- Fn::ImportValue:
!Sub '${StagingArea}-PrivateSubnet1'
- Fn::ImportValue:
!Sub '${StagingArea}--PrivateSubnet2'

Value of property IamInstanceProfile must be of type String

I want to reference my instance profile value from another stack.
If the Instance profile resource would be in the template, I could !Ref Name of the resource
---
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
SSMInstanceProfileStack:
Description: instance profile stack
Type: String
Default: instance-profile
Resources:
Ec2:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-077a5b1762a2dde35
IamInstanceProfile:
- Fn::ImportValue:
Fn::Sub: "${SSMInstanceProfileStack}-Suffix"
Tags:
- Key: Name
Value: Ec2SandPit
Outputs:
Ec2Output:
Description: A bare bone Ec2 instance
Value: !Ref Ec2
Export:
Name: !Sub "${AWS::StackName}-Ec2"
I am getting this error, the resource is deployed.
Value of property IamInstanceProfile must be of type String
Is there a fix for this?
IamInstanceProfile should be a string only, not a list of strings. So it should be (remove -):
IamInstanceProfile:
Fn::ImportValue:
Fn::Sub: "${SSMInstanceProfileStack}-Suffix"

Value of property Parameters must be an object with String (or simple type) properties

I am trying to pass parameters to one of the nested stacks by populating the values from another nested stacks output.
And i do not want any cross-referencing (unless there is no way around it)
The idea is pretty straight forward.
RootStack
-NstdStackVPC
-NstdStackSG
-NstdStackEC2
The problem is on the last nested stack while creating EC2.
If i created the resource in the root stack directly the EC2 gets created
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
But if i try to create the EC2 as a nested stack
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
By changing the root stack as follows
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
It gives me the following error:
Value of property Parameters must be an object with String (or simple type) properties
tried removing all the parameters to try one by one. But it fails on everything.
Even for the parameters that are being referenced directly from the root stack i.e., MyKeyName, EC2ImageId
I ran into the same exact error message with a similar problem and solution. I came here and since the issue was slightly different, this question helped me get to my solution. So, not trying to hijack this question, simply hoping to provide what I found additionally useful to the next person visiting.
I was nesting a cluster template very similar to this one and OPs example. Passing Subnets as a list of strings (I believe List<AWS::Some::Type> will also work).
Subnets:
Description: Subnets of the of the cluster availaibility zone
Type: CommaDelimitedList
Default: subnet-0d..de,subnet-0e..7a,subnet-0b..24
And I'm using the above parameters to call the partial child template as follows.
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]
So, In the above example, the SecurityGroups are joined together into a list from the output of the SecurityGroup Nested Template, but the subnets are simply joined together from the comma delimited parameter. There is a knowledge-center article too, if you want more info. TA OP
Ok finally sorted this out myself.
In my NstdStackSG outputs section i was referring to the object itself.
And that is where this goes wrong.
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
And now in the 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
And in my 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
Hope this helps. (If not in solving then at least in pointing the right direction)

How to launch an Amazon EC2 in a particular VPC in YAML CloudFormation template

How can I launch an Amazon EC2 instance in a particular subnet of a VPC using a YAML template in CloudFormation?
If anyone comes access this in the future, I was able to solve this by specifying the following: AvailabilityZone, SecurityGroupIds (not SecurityGroups), and SubnetId.
Resources:
EC2Instance:
Properties:
AvailabilityZone: us-east-1b
ImageId: ami-Id
InstanceType:
Ref: InstanceType
KeyName:
Ref: KeyName
Tags:
-
Key: "Name"
Value:
Ref: InstanceName
SecurityGroupIds:
- sg-idHere
SubnetId: subnet-idHere
Type: "AWS::EC2::Instance"
Make sure that the security group is available to the VPC you are trying to use. The SubnetId should represent the VPC.
Hierarchy:
VPC->SubnetID->SecurityGroupId
Here is the CF template for create a ec2 instance in region singapore. I have just used this template. If you are running in the other region please change ImageId name to met with you region
---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC with private subnets in two availability zones'
Parameters:
PrivateSubnet:
Description: Private Subnet to Attach NAT Gateway.
Type: AWS::EC2::Subnet::Id
InstanceType:
Description: EC2 instance type
Type: String
Default: t2.micro
AllowedValues: [t2.micro, t2.small, t2.medium, t2.large, m3.medium, m3.large,
m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge,
c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge,
c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge,
r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge]
ConstraintDescription: Please choose a valid instance type.
SSHKeyName:
Description: EC2 instance type
Type: String
ConstraintDescription: Please choose a valid KeyName
VolumeSize:
Description: size of volume
Type: Number
Default: 20
ConstraintDescription: Please choose a valid Number
AllowedValues: [20, 30, 40, 50]
IOPS:
Description: total ipos
Type: Number
Default: 100
ConstraintDescription: Please choose a valid Number
AllowedValues: [100, 200, 500, 1000]
ImageId:
Type: String
Description: 'value for region singapore. If you using other version please choose right'
Default: 'ami-33e4bc49'
Resources:
EC2Example:
Type: "AWS::EC2::Instance"
Properties:
SubnetId: !Ref PrivateSubnet
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
KeyName: !Ref SSHKeyName
BlockDeviceMappings:
-
DeviceName: /dev/sda1
Ebs:
VolumeType: io1
Iops: !Ref IOPS
DeleteOnTermination: false
VolumeSize: !Ref VolumeSize
Outputs:
EC2Example:
Description: 'Ec2 instance EC2Example'
Value: !Ref EC2Example
Export:
Name: !Sub '${AWS::StackName}-EC2Example'
The CloudFormation template includes a SubnetId parameter:
Type: "AWS::EC2::Instance"
Properties:
SubnetId: String
Simply insert the ID of the existing Subnet (eg subnet-1234abcd).