10

At the moment I have a shared S3 bucket which has specific access to particular key paths (i.e. folders) for different instances. I've been able to create instance profile with my new role and test no problem limiting to access to that folder.

My problem is that there is an existing generic role with defined policies, that I also want to be able to include in my new role for each stack.

In cloudformation is it possible to include policies defined in one role to be included in another role without having to redefine the policy document in the new role?

Something like the following:

"AppTierS3AccessRole": {
        "Type": "AWS::IAM::Role",
        "Properties": {
            "AssumeRolePolicyDocument": {
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Principal": {
                            "Service": [ "ec2.amazonaws.com" ]
                        },
                        "Action": [ "sts:AssumeRole" ]
                    }
                ]
            },
            "Path": "/",
            "Policies": [ { "Ref": "existing-policy" } ]
        }
    },

The "existing-policy" being the important part here. I have tried to find the arn of the existing policy to try and reference it but I'm a bit stuck.

hughmcmanus
  • 201
  • 1
  • 2
  • 3

4 Answers4

16

src: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html

The AWS::IAM::Role types now have a ManagedPolicyArns field where you can set this. You just need to grab the ARN (easy to grab from IAM console) and place it in that field. In the example below I created a role that provides read-only ECR access so my image can pull docker containers from ECR.

  ecrRole:
    Type: AWS::IAM::Role
    Properties:
      Path: "/"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - ec2.amazonaws.com
          Action:
          - sts:AssumeRole
4

You can achieve this by using managed policies. Put the defined policy that you want to share in a customer managed policy, then attach that defined policy to each role where you want to use it. Any future changes to your managed policy will immediately be applied to all the roles that have the managed policy attached.

You can either create the customer managed policy in CloudFormation, through a AWS::IAM::ManagedPolicy resource, or attach an existing managed policy.

markusk
  • 495
1

To expand on @markusk's answer re: Managed Policies - yes, that.

Example:

"ManagedPolicy": {
  "Type": "AWS::IAM::ManagedPolicy",
  "Properties": {
    "Description": "something descriptive",
    "Groups": [ ... ref(s) for groups ... ],
    "Roles: [{"Ref":"AppTierS3AccessRole"}],
    "Users": [ ... ref(s) for users ... ],
    "PolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        ...
      ]
    }
  }
}
Peter Mounce
  • 1,273
-1

No, you cannot embed one role in another role at this time. The only alternatives I can think of are:

  • Create a new instance profile with AWS::IAM::InstanceProfile and assign the existing generic role to it.
  • Before creating your CloudFormation stack, run a script that duplicates the generic role. e.g. It creates a new role, lists all the policies for the existing generic role and re-creates them in the new role. Then, you can assign the new role to a new AWS::IAM::InstanceProfile resource in your template and use it for your EC2 instance(s) or launch configuration(s).
dialt0ne
  • 3,075