AWS Cloudformation - CodeCommit - Deny Push to Master - amazon-web-services

So here is the situation:
I have a Cloudformation that creates CodeCommit repositories with some extra resources for other devops processes to work.
I got the requeriment to block users from doing a push to a specific branch, in this case master, I have found the policy that does that. source: https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-conditional-branch.html
So I write a role and policy with the following:
Resources:
CodeCommitRepository:
Type: AWS::CodeCommit::Repository
Properties:
RepositoryName: !Sub '${ProjectCode}-${ProjectName}-${ComponentName}'
RepositoryDescription: !Ref CodeCommitRepositoryDescription
Tags:
- Key: fdr:general:project-code
Value: !Ref ProjectCode
- Key: fdr:general:project-name
Value: !Ref ProjectName
DenyPushRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${ProjectCode}-${ProjectName}-${ComponentName}-DenyPush-Role'
ManagedPolicyArns:
- !Ref DenyPushToMasterPolicy
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- codecommit.amazonaws.com
DenyPushToMasterPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub '${ProjectCode}-${ProjectName}-${ComponentName}-DenyPush-Policy'
Description: Policy to deny push to master
PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- codecommit:GitPush
- codecommit:PutFile
- codecommit:DeleteBranch
- codecommit:MergePullRequestByFastForward
Effect: Deny
Resource: !GetAtt CodeCommitRepository.Arn
Condition:
StringEqualsIfExists:
codecommit:References:
- refs/heads/master
'Null':
codecommit:References: 'false'
As I understand which I wouldn't say is much, by creating the Role with the Policy and the sts:AssumeRole I thought that any user using that repository will assume that role that denys them the ability to push to master but that wasn't the case.
I guess that we may be overcomplicating things and we should put that policy unto all users directly on IAM but the idea is to have it done very granular. What am I doing wrong or is it even possible?.
Best regards

DenyPushRole is not for any users. You specified it to be only for codecommit.amazonaws.com which is incorrect.
Users do not automatically assume any roles. They have to explicitly assume your DenyPushRole using AssumeRole API call. Your users must also have permission to sts:AssumeRole.
Thus your role, in a general form, should be:
DenyPushRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${ProjectCode}-${ProjectName}-${ComponentName}-DenyPush-Role'
ManagedPolicyArns:
- !Ref DenyPushToMasterPolicy
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
AWS:
- !Ref AWS::AccountId
Once the role exist, and the users have sts:AssumeRole to assume it, they will use the AssumeRole command to actually assume the role. This will give then new, temporary AWS credentials to perform any actions specified by the role. In your case, the role only denies, so they will not be able to do anything anyway. You would need to add some allow statements to the role for your uses to be actually able to do something, not only deny.

Related

AWS Cloudformation:Template validation error Role and policy

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.

AWS CloudFormation custom permissions boundary

Is it possible to write your custom permissions boundary policy inside the AWS CloudFormation for AWS Lambda's LambdaExecutionRole?
It could be best if I could write all the necessary policies for the LambdaExecutionRole inside this code instead of using !Ref or !Sub.
Please see the PermissionBoundary part
(This code doesn't work because of misconfigured permission boundary part)
LambdaExecutionRole:
Description: Creating service role in IAM for AWS Lambda
Type: AWS::IAM::Role
Properties:
RoleName: !Sub 'CodeStar-${ProjectId}-Execution${Stage}'
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action: sts:AssumeRole
Path: /
ManagedPolicyArns:
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
PermissionsBoundary: !Sub
Properties:
PolicyDocument:
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:DescribeLogGroups
- logs:PutLogEvents
- xray:Put*
Effect: Allow
Resource: '*'
Sadly you can't do this. PermissionsBoundary requires ARN to IAM policy. So first you have to create AWS::IAM::ManagedPolicy and then reference it's ARN in PermissionsBoundary.

How to assume AWS role from the same AWS role in CloudFormation template?

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'

AWS IAM Cloudformation YAML template errror: 'null' values are not allowed

I am working on a Cloudformation template for an IAM role that grants cross account read only access. It uses a managed policy for Readonly access as well. So far, I've resolved several errors, but now I'm getting a "'null' values are not allowed in templates" error when I try to validate the template. I think it's a space or syntax thing, but I cannot be sure as it's my first time creating a cloudformation template from scratch and using YAML.
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation template IAM Role for New Relic to have read access to AWS account
Resources:
NewRelicInfrastructure-IntegrationsRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
Effect: Allow
Principal:
AWS: 11111111
Action: sts:AssumeRole
Condition:
StringEquals:
sts:ExternalId: '11111'
Path: '/'
ManagedPolicyArns: arn:aws:iam::aws:policy/ReadOnlyAccess
RoleName: NewRelicInfrastructure-Integrations2
The problem is with AssumeRolePolicyDocument:. It's required but you left it empty. You also have an indentation issue where Path, ManagedPolicyArns and RoleName are under Resources instead of Properties.
Try:
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation template IAM Role for New Relic to have read access to AWS account
Resources:
NewRelicInfrastructure-IntegrationsRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
Effect: Allow
Principal:
AWS: 11111111
Action: sts:AssumeRole
Condition:
StringEquals:
sts:ExternalId: '11111'
Path: '/'
ManagedPolicyArns: arn:aws:iam::aws:policy/ReadOnlyAccess
RoleName: NewRelicInfrastructure-Integrations2
Indentation fixed, it was specifying something in AssumeRolePolicyDocument, but the YAML syntac wasn't correct, this worked:
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation template IAM Role for New Relic to have read access to AWS account
Resources:
NewRelicInfrastructureIntegrationsRole:
Type: AWS::IAM::Role
Properties:
Path: '/managed/'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/ReadOnlyAccess'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
-
Action: sts:AssumeRole
Effect: Allow
Principal:
AWS: 1111111111111
Condition:
StringEquals:
sts:ExternalId: '11111'
RoleName: NewRelicInfrastructureIntegrationsRole
Use YAML interpreter online to show you where you might be getting a null value in your yaml file. They're hard to spot as a wrong indentation can result in a null value - the yaml interpreter will show you in json where you're getting that value.

Cloudformation and Roles... but mostly roles

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.