CloudFormation stack creation failing with "Value (IAM Name) for parameter iamInstanceProfile.name is invalid. "
amazon web services - Associate existing IAM role with EC2 instance in CloudFormation - Stack Overflow
Why Do EC2s Use IAM Instance Profiles Instead of Using IAM Roles Directly?
I agree this does seem like an anti-pattern compared to their modern computing services like lambda, as you pointed out.
I would bet its basically a legacy pattern that they haven't gotten around to replacing yet because of backwards compatibility issues or the the engineering complexity involved, etc.
Would be curious to hear an official reasoning from AWS.
More on reddit.comWhat is an EC2 Instance Profile?
Videos
I was going through Documentation and couldn't figure out what Instance profile is. It says it is a container for IAM role. But why? Like other services have nothing like that. What does it do and what is its purpose?
The doc also says that you have to manually create Instance profile when creating from cli, cloudformation etc. I don't remember creating it when using Terraform or CDK.
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
You can use an existing InstanceProfile instead of creating a new one from within the stack. In fact, one might already be created for you - from the docs:
If you use the AWS Management Console to create a role for Amazon EC2, the console automatically creates an instance profile and gives it the same name as the role.
This means that you might not have to create an AWS::IAM::InstanceProfile resource in the stack. However note that also:
The console does not create an instance profile for a role that is not associated with Amazon EC2.
In this case you can do it manually from AWS CLI using these 2 commands:
aws iam create-instance-profile --instance-profile-name MyExistingRole
aws iam add-role-to-instance-profile --instance-profile-name MyExistingRole --role-name MyExistingRole
Then, provided you've defined a role in the UI named MyExistingRole, this will be sufficient:
"Resources" : {
"Instance" : {
"Type" : "AWS::EC2::Instance",
...
"Properties" : {
"IamInstanceProfile" : "MyExistingRole",
...
}
}
}
You need an instance profile, a role, and the instance info (or launch configuration) itself.
Your instance profile would look like this:
"Resources" : {
"InstanceProfile" : {
"Type" : "AWS::IAM::InstanceProfile",
"Properties" : {
"Path" : "/",
"Roles" : ["MyExistingRole"]
}
},
"Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"IamInstanceProfile" : {"Ref" : "InstanceProfile"}
...
}
}
In particular - note that the reference in the Instance profile is to an existing RoleName
Also - I've written about bootstrapping instances which uses instance profiles and roles to ensure we're not persisting security.
The key thing is rather than using the {"Ref" : RoleName} etc, to use the actual name of the role.