Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I reference an existing role in my new CloudFormation template?

In my AWS account, I am building a new Cloudformation template that creates new policies, and I want to attach those to a few existing roles in the account. Here is how I have been trying to reference them:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Names of existing roles to which the restrictive policies need added",
    "Parameters": {
        "AdditionalExecutionRoleParameter": {
            "Type": "AWS::IAM::Role",
            "Default": "CloudOps"
        }
    },
    "Resources": { (and so on)

Then down in the section below the new policies, I have been trying to reference these existing roles ("AdditionalExecutionRoleParameter" in this case) and attach the policies to them using the Roles parameter. However, I keep getting a "failed to retrieve external values" error when trying to deploy the CloudFormation template... I've tried inputting "CloudOps", which is the role name, as the parameter "Default", and I've also tried inputting the role ARN there... nothing is working.

like image 618
lorena Avatar asked Jan 26 '23 04:01

lorena


1 Answers

Not all AWS resource types are supported in the parameter type field.

The full list is at AWS-Specific Parameter Types. It includes, for example:

  • AWS::EC2::VPC::Id
  • List<AWS::EC2::VPC::Id>
  • AWS::SSM::Parameter::Name

This list does not include AWS::IAM::Role (or any IAM resources).

If you're simply trying to associate a new IAM policy with an existing named IAM role, then note that the AWS::IAM::Policy construct has a Roles property and you should supply a list of role names to apply the policy to. It requires role names, not role ARNs, so you don't need the account ID.

If you do ever need the account ID then it's available as a pseudo-parameter and you can get it from "Ref" : "AWS::AccountId", but I don't think you need it here.

Here's a JSON example of how to create a new IAM policy (allowing s3:Get* on mybucket/*) and associate it with an existing IAM role, whose name you supply as a parameter to the stack:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Add policy to role test",
  "Parameters": {
    "TheRoleName": {
      "Type": "String",
      "Default": "CloudOps",
      "Description": "Name of role to associate policy with"
    }
  },
  "Resources": {
    "ThePolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": "s3-read",
        "PolicyDocument": {
          "Statement": {
            "Effect": "Allow",
            "Action": [
              "s3:Get*"
            ],
            "Resource": ["arn:aws:s3:::mybucket/*"]
          }
        },
        "Roles": [
          {
            "Ref": "TheRoleName"
          }
        ]
      }
    }
  }
}
like image 63
jarmod Avatar answered Jan 29 '23 07:01

jarmod