Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloudformation how to reference Managed-Policy from another stack

I have the following role. From within it I want to use an existing managed policy from another stack.

How can I do so?

"TestRole": {
    "Properties": {
      "AssumeRolePolicyDocument": {
        "Statement": [
          {
            "Action": [
              "sts:AssumeRole"
            ],
            "Effect": "Allow",
            "Principal": {
              "Service": [
                "lambda.amazonaws.com"
              ]
            }
          }
        ],
        "Version": "2012-10-17"
      },
      "Path": "/lambda/",
      "Policies": [
        ??????
      ]
    },
    "Type": "AWS::IAM::Role"
  }
like image 653
lony Avatar asked Mar 09 '16 15:03

lony


People also ask

How do I refer to a resource in another AWS CloudFormation stack during template creation?

Note: To reference a resource in another AWS CloudFormation stack, you must create cross-stack references. To create a cross-stack reference, use the export field to flag the value of a resource output for export.

What is cross-stack reference CloudFormation?

Cross-stack references let you use a layered or service-oriented architecture. Instead of including all resources in a single stack, you create related AWS resources in separate stacks; then you can refer to required resource outputs from other stacks.


2 Answers

There's now a supported way to do this, using Imports/Exports. Basically, the stack that creates the policy has an output that contains the policy name (or ARN, not sure which is needed in this case), and declares it as an export with a regionally-unique name. Then, other stacks can consume it using the Import function.

For example, if the following stack (let's say it's named FooStack) creates the managed policy, it can have the following in its output:

"Outputs" : {
    "MyManagedPolicy" : {
        "Value" : { "Ref" : "MyManagedPolicy" },
        "Export" : { "Name" : {"Fn::Sub": "${AWS::StackName}-MyManagedPolicy" }}
    }
}

The other stack can use it:

"Policies": [
    { "Fn::ImportValue" : "FooStack-MyManagedPolicy" }
]
like image 120
LiVi Avatar answered Oct 17 '22 14:10

LiVi


If your requirement is a stand-alone sharable policy. then you need to make it as ManagedPolicy and not a standard Policy.

An Example:

1

MyManagedPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
  Path: "/"
  PolicyDocument:
    Version: "2012-10-17"
    Statement:
      - Effect: "Allow"
        Action:
          - "s3:*"
        Resource:
          - Fn::GetAtt: MyBucket.Arn

2

Export it:

MyManagedPolicy:
Description: MyManagedPolicy
Value:
  Ref: MyManagedPolicy
Export:
  Name:
    Fn::Join:
      - "-"
      - - "MyManagedPolicy"
        - Ref: StackName

Then in your other stack where you want to import this stand-alone managed policy in one of your roles, do this:

MyUserRole:
Type: "AWS::IAM::Role"
Properties:
  RoleName: "SomeName"
  AssumeRolePolicyDocument:
    Version: "2012-10-17"
    Statement:
      - Effect: "Allow"
        Principal:
          AWS: 
            - .....
        Action:
          - .....  
  Path: "/"
  ManagedPolicyArns:
    - Fn::ImportValue:
        Fn::Sub: "MyManagedPolicy-${StackName}"
  Policies:
    - PolicyName: "NameOfYouInlinePolicyWithoutSpaces"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - .....
            Resource:
              - .....
like image 1
VAS11 Avatar answered Oct 17 '22 16:10

VAS11