Reputation: 1999
I want to create a EC2 instance type t3.medium
on all environments and m5.large
on production.
I'm using .ebextensions
(YAML) like so:
option 1:
Mappings:
EnvironmentMap:
"production":
TheType: "m5.large"
SecurityGroup: "foo"
...
"staging":
TheType: "t3.medium"
SecurityGroup: "bar"
...
option_settings:
aws:autoscaling:launchconfiguration:
IamInstanceProfile: "aws-elasticbeanstalk-ec2-role"
InstanceType: !FindInMap
- EnvironmentMap
- !Ref 'AWSEBEnvironmentName'
- TheType
SecurityGroups:
- {"Fn::FindInMap": ["EnvironmentMap", {"Ref": "AWSEBEnvironmentName"}, "SecurityGroup"]}
Option 2:
InstanceType: {"Fn::FindInMap": ["EnvironmentMap", {"Ref": "AWSEBEnvironmentName"}, "EC2InstanceType"]}
Option 3:
InstanceType:
- {"Fn::FindInMap": ["EnvironmentMap", {"Ref": "AWSEBEnvironmentName"}, "EC2InstanceType"]}
Option 1 fails with Invalid Yaml (but I took this from this AWS example.
Option 2 and 3 fail with the same problem.
The FindInMap function is not "called":
Invalid option value: '{"Fn::FindInMap":["EnvironmentMap","EC2InstanceType"]},{"Ref":"AWSEBEnvironmentName"}' (Namespace: 'aws:autoscaling:launchconfiguration', OptionName: 'InstanceType'): Value is not one of the allowed values: [c1.medium, c1.xlarge, c3.2xlarge, ....
It tries to interpret the whole function/thing as a string.
For the SecurityGroups
property it works, for InstanceType
it does not.
I can't do it dynamically and I can't find how to achieve this neither on AWS doc, SO, or anywhere else. I would assume this is simple stuff. What am I missing?
EDIT:
Option 4: using conditionals
Conditions:
IsProduction: !Equals [ !Ref AWSEBEnvironmentName, production ]
option_settings:
aws:autoscaling:launchconfiguration:
InstanceType: !If [ IsProduction, m5.large, t3.medium ]
SecurityGroups:
- {"Fn::FindInMap": ["EnvironmentMap", {"Ref": "AWSEBEnvironmentName"}, "SecurityGroup"]}
Error: YAML exception: Invalid Yaml: could not determine a constructor for the tag !Equals in...
But this comes from documentation on conditions and if.
EDIT 2:
I eventually found out that the option InstanceType
is obsolute and we should use:
aws:ec2:instances
InstanceTypes: "t3.medium"
But alas, this does not solve the problem either because I cannot use the replacement functions here as well (Fn:findInMap
).
Upvotes: 4
Views: 643
Reputation: 399
I know this is an old question, but for anyone else searching, instead of trying to dynamically or conditionally set the instance type in an ebextensions config file, you can just entirely omit that config option and instead include the --instance_type
flag in the eb create
command (https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb3-create.html#eb3-createoptions):
eb create --instance_type t4g.small [...]
Now since your ebextensions has no reference to the instance type/size, when you deploy, the original option won't get overridden. You can change the instance type within the running environment through the web console.
Upvotes: 0
Reputation: 238747
The reason why FindInMap
does not work in option_settings
is the fact that only four intrinsic functions are allowed there (from docs):
I'm not convinced that SecurityGroups
worked. I think your script failed before FindInMap
in SecurityGroups
got chance to be evaluated.
However, I tried to find a way using Resources. The closes I got was with the following config
file:
Mappings:
EnvironmentMap:
production:
TheType: "t3.medium"
staging:
TheType: "t2.small"
Resources:
AWSEBAutoScalingLaunchConfiguration:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
InstanceType:
? "Fn::FindInMap"
:
- EnvironmentMap
-
Ref: "AWSEBEnvironmentName"
- TheType
Although this is a step closer, it ultimately fails as well. The reason is that when EB is jointing our Resources
config file with its own template, it produces the following:
"InstanceType": {
"Ref": "InstanceType", # <--- this should NOT be here :-(
"Fn::FindInMap": [
"EnvironmentMap",
{
"Ref": "AWSEBEnvironmentName"
},
"TheType"
]
},
instead of
"InstanceType": {
"Fn::FindInMap": [
"EnvironmentMap",
{
"Ref": "AWSEBEnvironmentName"
},
"TheType"
]
},
And this happens because the original InstanceType
(before the joint operation) is:
"InstanceType":{"Ref":"InstanceType"},
Therefore, EB instead of replacing InstanceType
with our custom InstanceType
provided in our config file, it just merges them.
Upvotes: 1