5
votes

I've got a CloudFormation template that brings up an auto-scaling group. It has the below instance profile and associated role and policy. Is there any way to also add an existing IAM role to the InstanceProfile? The AWS docs seem to say no:

Currently, a maximum of one role can be assigned to an instance profile.

Basically I want to leave the below role and policy creation in the template so the policy can reference the SQS resource (i.e. "Resource": [{ "Fn::GetAtt" : ["LifecycleSQS", "Arn"] }]) created by the template, while also assigning a pre-existing role that will give permissions to apps on the instances. I don't want to create these app specific permissions in the CloudFormation template.

"InstanceRole":{
     "Type":"AWS::IAM::Role",
     "Properties":{
        "AssumeRolePolicyDocument":{
           "Statement":[
              {
                 "Effect":"Allow",
                 "Principal":{
                    "Service":[
                       "autoscaling.amazonaws.com"
                    ]
                 },
                 "Action":[
                    "sts:AssumeRole"
                 ]
              }
           ]
        },
        "Path":"/"
     }
},
"RolePolicies":{
     "Type":"AWS::IAM::Policy",
     "Properties":{
        "PolicyName": "MyRolePolicy,
        "PolicyDocument":{
           "Statement":[
              {
                  "Effect": "Allow",
                  "Resource": [{ "Fn::GetAtt" : ["LifecycleSQS", "Arn"] }],
                  "Action": [
                        "sqs:SendMessage",
                        "sqs:GetQueueUrl",
                        "sns:Publish"
                  ]
              }
           ]
        },
        "Roles":[
           {
              "Ref":"InstanceRole"
           }
        ]
     }
},
"InstanceProfile":{
     "Type":"AWS::IAM::InstanceProfile",
     "Properties":{
        "Path":"/",
        "Roles":[
           {
              "Ref":"InstanceRole"
           }
        ]
     }
}
1

1 Answers

9
votes

That is correct, Roles in an instance profile are limited to 1. You cannot get around this.

I have found that is less of a limitation if you create discrete policies that are then applied to a given instance role.

So for example, I have an instance role of ApplicationServer. I can then create and attach the following policies to that Role: CodeDeployInstance (allow that instance to accept code deployments), DomainJoinInstance (permissions that allow the instance to join the domain), and AppCredentialsInstance (allow the instance to access app credentials via a secured S3 bucket). You can attached up to 10 policies to a Role in this way.

You can create these policies outside the CF template, and apply them to the Instance Role/Instance Profile as/when needed.

I define all my instances in that way: a specific role name, and then add/subtract/combine my own pre-defined policies against any role as needed.

These changes are recognized immediately by the running instance, with needing any reboot or restart.

I hope that helps.