I'm trying to select an AMI dynamically based on the Instance Family. The instance family being determined from the first few letters (before the period) from the InstanceType.
I would think that the following CloudFormation snippet would work. It uses !Select
and !Split
to find the first few characters of the InstanceType. The Instance Family should be passed as the third argument to FindInMap. However, it fails with the error:
An error occurred (ValidationError) when calling the CreateStack operation: Template error: every Fn::FindInMap object requires three parameters, the map name, map key and the attribute for return value
AWSTemplateFormatVersion: 2010-09-09
Description: my new server
Parameters:
InstanceType:
Description: Instance Type
Type: String
AllowedValues:
- t2.micro
- t3a.small
- t3a.medium
- t4g.micro
- t4g.small
- t4g.medium
Mappings:
AmiMap:
us-east-1:
## AMD64 Instances
t2: ami-0f65ab0fd913bc7be
t3a: ami-0f65ab0fd913bc7be
## Graviton (ARM) Instances
t4g: ami-0cf2a935e8b19b29b
Resources:
LaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
...
ImageId: !FindInMap
- AmiMap
- "us-east-1"
- !Select [0, !Split [".", !Ref InstanceType ]]
Why isn't the !Select ... !Split
line returning a string for FindInMap
to recognize?
As recognized by @Paolo and @Marcin, !Select
can't be used inside a !FindInMap
. The full instance type (ie: t4g.small
) can't be used as keys inside the Mappings
section either, since they contain non alpha-numeric characters.
I feel like this is a better solution, rather than trying to split the instance type (t4g.small
) to find the Instance Family, it constructs the InstanceType
from an InstanceFamily
+ InstanceSize
. That way, we can use the InstanceFamily
inside the Mappings.
AWSTemplateFormatVersion: 2010-09-09
Description: My Server
Parameters:
InstanceFamily:
Description: "Instance Family ie: t4g, t3a, m5)"
Type: String
AllowedValues:
- t2
- t3
- t3a
- t4g
InstanceSize:
Description: "Instance Size (micro, small, medium, large)"
Type: String
AllowedValues:
- micro
- small
- medium
- large
Mappings:
AmiMap:
## Last Updated 2022-07-01
us-east-1:
## AMD64 Instances. Ubuntu 22.04 us-east-1
t2: ami-0f65ab0fd913bc7be
t3: ami-0f65ab0fd913bc7be
t3a: ami-0f65ab0fd913bc7be
## Graviton (ARM) Instances Ubuntu 22.04 us-east-1
t4g: ami-0cf2a935e8b19b29b
Resources:
LaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
AssociatePublicIpAddress: true
BlockDeviceMappings:
...
ImageId: !FindInMap
- AmiMap
- "us-east-1"
- !Ref InstanceFamily
InstanceType: !Join ['.', [!Ref InstanceFamily, !Ref InstanceSize]]
InstanceMonitoring: false
...