If defining a SSM parameter in cloud formation one template like this
KinesisStreamARNParameter:
Type: AWS::SSM::Parameter
Properties:
Name: !Sub "/${Environment}/Services/${Domain}/kinesis_stream_arn"
Type: String
Value: !GetAtt KinesisStream.Arn
How would I use in a different template file that defines a role? How would I refer to it under resources for the policy?
KinesisFirehoseRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: firehose.amazonaws.com
Action: sts:AssumeRole
Path: /
Policies:
- PolicyName: KinesisFirehosePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- kinesis:*
- s3:*
- s3-object-lambda:*
Resource:
- !Sub "${Bucket.Arn}/*"
Generally there are two choices:
Export the arn of your KinesisStreamARNParameter in the outputs. Then use ImportValue to reference it your second template.
Pass the arn as an input parameter to your second template. This will require you to manually provide the value when you deploy the second template, or create some automation wrapper that will populate that value for you before deployment.
Related
I am new to cloudformation and trying to create a template that can create a execution role and associated policies for my lambda function.
AWSTemplateFormatVersion: 2010-09-09
Description: AWS CloudFormation Template for creating iam role for SSM lambda
Parameters:
rolename:
Type: String
Description: The name of the iam role for SSM Lambda
Default: SSM_lambda_role
policyname:
Type: String
Description: pcluster lambda iam policy for SSM Lambda
Default: SSM_lambda_policy
Resources:
ssmlambdarole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Sub '${rolename}'
Description: iam role for ssm lambda role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- !Sub 'arn:aws:iam::${AWS::AccountId}:policy/${policyname}'
ssmlambdapolicy:
Type: 'AWS::IAM::ManagedPolicy'
Properties:
ManagedPolicyName: !Sub '${policyname}'
Description: The name of the iam role for SSM Lambda
Path: '/'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- logs:CreateLogGroup
Resource: arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*
Effect: Allow
Sid: CloudWatchLogsPolicy
- Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${policyname}:*
Effect: Allow
Sid: CloudWatchLogsPolicy
- Action:
- ssm:Describe*
- ssm:Get*
- ssm:List*
Resource: "*"
Effect: Allow
If I define a role first in the above template, I get an error during stack creation mentioning that the policy is not found and if I create policy first in the above order, I keep getting a validation error. can someone tell me where am I getting wrong.
There is an attribute that can help to achieve that: DependsOn,
but the better way is to use - !Ref ssmlambdapolicy instead of - !Sub 'arn:aws:iam::${AWS::AccountId}:policy/${policyname}'.
In each case, it will establish a dependency between resources. Thanks to that AWS will be able to recognize resource creation orders - you didn't use any of them, so AWS 1stly tries to create a role (or policy, depending on the order in the template), and attach a policy that doesn't exist yet.
The validation error is due to that you missed !sub in the policy statements.
Btw, I strongly recommend looking for help in CFN documentation - sometimes there is a section with use-case examples.
I'm using an IAM role for a glue job that makes some data processing, to accomplish this task I need to assume the role that executes the glue role.
As example, in the following cloudformation template the IAM::Policy has permission to query from a Dynamo DB table and to get Objects from an s3 bucket.
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
GlueAccessPolicy:
Type: AWS::IAM::Policy
Properties:
Roles:
- !Ref GlueRole
PolicyName: glue_access_policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: 's3:getObject'
Resource:
- 's3_bucket_arn'
- Effect: Allow
Action:
- 'dynamodb:DescribeTable'
- 'dynamodb:Query'
Resource:
- 'dynamo_table_arn'
GlueRole:
Type: 'AWS::IAM::Role'
Properties:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: 'Allow'
Principal:
Service:
- 'glue.amazonaws.com'
Action:
- 'sts:AssumeRole'
Now, this question illustrates an example to assume role B from role A, switching roles.
So, I have the question if is it possible or valid for GlueRole to assume GlueRole ?
As there is no limitation for the role to assume itself, and the docs state the following
A policy that grants a user permission to assume a role must include a statement with the Allow effect on the following:
The sts:AssumeRole action
The Amazon Resource Name (ARN) of the role in a Resource element
it is straightforward to add this policy to the AWS::IAM::Policy resource on the CloudFormation template.
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
GlueAccessPolicy:
Type: AWS::IAM::Policy
Properties:
Roles:
- !Ref GlueRole
PolicyName: glue_access_policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: 'sts:AssumeRole'
Resource: !GetAtt GlueRole.Arn
GlueRole:
Type: 'AWS::IAM::Role'
Properties:
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: 'Allow'
Principal:
Service:
- 'glue.amazonaws.com'
Action:
- 'sts:AssumeRole'
I was looking at the Condition Function Fn::If: to create or provision a resource only if a condition is evaluated to true. In my case, created a policy if the environment is prod.
Parameters:
Env:
Description: Environment
Type: String
Conditions:
IsProd: !Equals [!Ref Env, 'prod']
I know how to do it for a property, but not for the entire resource block.
Type: 'AWS::IAM::Policy'
Properties:
PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: '*'
Resource: '*'
Roles:
- !Ref RootRole
Is this something possible?
You can do it using Condition: resource attribute. For example:
Resources:
MyIAMPolicy:
Condition: IsProd
Type: 'AWS::IAM::Policy'
Properties:
PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: '*'
Resource: '*'
Roles:
- !Ref RootRole
More on this can be found here:
Conditionally launch AWS CloudFormation resources based on user input
I have defined an IAM policy for Dynamodb cloud formation template as shown below, and I am getting the following error:
Value of property Users must be of type List of String
Any ideas what am I doing wrong?
myDynamoPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
Sid: AllAPIActionsOnBooks
Effect: Allow
Action: dynamodb:*
Resource:
Ref: myDynamoDBTable
PolicyName: DynamoDBOwnerPolicy
Users:
Ref: IAMUsers
Per AWS documentation, the Users property must be an array. It should look like this:
myDynamoPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
Sid: AllAPIActionsOnBooks
Effect: Allow
Action: dynamodb:*
Resource:
Ref: myDynamoDBTable
PolicyName: DynamoDBOwnerPolicy
Users:
-
Ref: "IAMUsers"
CloudFormation template reference can be found here.
I'm fairly new to AWS I created a role and now I've found I need another. Is there away to join multiple roles to make another or do I have to just build something new ?
Resources:
ECROLE:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser
EXTRAROLE:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
ECROLEINSTANCEPROFILE:
Type: "AWS::IAM::InstanceProfile"
Properties:
Path: /
Roles:
- !Ref ECROLE
I'd like to just add something here ... - !Ref EXTRAROLE
InstanceProfileName: ECROLEINSTANCEPROFILE
Outputs:
ECROLEKEY:
Description: Role to be used for interacting with ECR.
Value: !Ref ECROLE
Export:
Name: ECROLEOUTPUT
In the AWS::IAM::InstanceProfile" stanza I've put the kind of thing I was thinking ...
Thanks
The Roles property in AWS::IAM::InstanceProfile is currently limited to exactly 1 Role (see AWS::IAM::InstanceProfile Roles.
Creating a new Role is going to be your best bet.
If you find that you are sharing permissions between a number of different roles, then creating reusable Managed Policies will help with that. That said, in your example, you're already using existing managed policies.