I have a situation:
Resources:
- ${file(resources/default-role.yml)}
- ${file(resources/secondary-role.yml)}
where default-role.yml:
Resources:
DefaultRoleForLambdas:
Type: AWS::IAM::Role
Properties:
RoleName: defaultRoleForLambdas
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
Policies:
- PolicyName: defaultPolicyForLambdas
PolicyDocument:
Version: "2012-10-17"
Statement:
- ${file(iam/s3-iam.yml):S3Policies}
- ${file(iam/dynamodb-iam.yml):DynamoDbPolicies}
So this would be my default role for provider iam roles.
In serverless:
iam:
role: DefaultRoleForLambdas
But I want to have some functions with role that have those 2 basic privileges + some others, so in secondary-role I have. I overwrite that role in this function:
handler: src/some-handler
role: SecondaryRoleForLambdas
Resources:
SecondaryRoleForLambdas:
Type: AWS::IAM::Role
Properties:
RoleName: secondaryRoleForLambdas
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: secondaryPolicyForLambdas
PolicyDocument:
Version: "2012-10-17"
Statement:
- ${file(iam/s3-iam.yml):S3Policies}
- ${file(iam/dynamodb-iam.yml):DynamoDbPolicies}
- ${file(iam/sqs-iam.yml):SqSPolicies}
For example sqs-iam.yml:
SqsIam:
Effect: Allow
Action:
- sqs:SendMessage
- sqs:ReceiveMessage
- sqs:DeleteMessage
- sqs:GetQueueAttributes
Resource:
- !Sub arn:aws:sqs:eu-west-1:${AWS::AccountId}:${self:service}-${self:provider.stage}*
I think you get my point now. I tried to add many roles for functions but it is not possible in serverelss AFAIK. (So when I have a default role - with s3 and dynamodb , I am not able to assign 2 roles to functions, so that 1 particular function would end up having those 3 polices), thats why I had to create a seperate role and repeat my two default policies and add particular one.
I thought I could improve my solution by having sth like this, but it does not work:
default-role.yml:
...
Statement:
- ${file(iam/common-iam.yml)}
secondary-role.yml:
...
- ${file(iam/common-iam.yml)}
- $file{(iam/sqs-iam.yml)}
where iam/common-iam.yml:
- ${file(iam/s3-iam.yml)}
- ${file(iam/dynamodb-iam.yml)}
But it does not work? Any ideas if that is even possible.
Related
I used this article to create my stack.
https://aws.amazon.com/blogs/infrastructure-and-automation/scheduling-automatic-deletion-of-aws-cloudformation-stacks/
But getting an error:
User:
arn:aws:sts::xxx:assumed-role/deleteCurrent-DeleteAfter-DeleteCFNLambdaExecution-T1WHQG2UTLWM/DeleteCFNLambda-deleteCurrent
is not authorized to perform: ssm:DeleteParameter on resource:
arn:aws:ssm:us-east-1:xxx:parameter/CFN-DemoParameter-plOl5Hg4QuI5
(Service: AmazonSSM; Status Code: 400; Error Code:
AccessDeniedException;
The template can be viewed here...
https://datameetgeobk.s3.amazonaws.com/cftemplates/delete_after_5m.template
Any suggestion to correct the error will be appreciated.
The error says that your lambda execution role does not have permissions to execute ssm:DeleteParameter role. Thus you can add the missing permission to the lambda role:
Resources:
DeleteCFNLambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: ["lambda.amazonaws.com"]
Action: "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: "lambda_policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "arn:aws:logs:*:*:*"
- Effect: "Allow"
Action:
- "cloudformation:DeleteStack"
Resource: !Sub "arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${StackName}/*"
- Effect: "Allow"
Action:
- "ssm:DeleteParameter"
Resource: "*"
I am trying to create a parameter and would like to combine !Sub and !Import several times.
Parameters:
Environment:
Description: Stackname of Environment
Type: String
Resources:
IAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: '*'
Action: ['sts:AssumeRole']
Path: /
Policies:
- PolicyName: S3Files
PolicyDocument:
Statement:
- Sid: 'S3Files'
Effect: Allow
Action:
- 's3:DeleteObjectTagging'
- 's3:GetObjectRetention'
- 's3:ListMultipartUploadParts'
- 's3:PutObject'
- 's3:GetObjectAcl'
- 's3:GetObject'
- 's3:AbortMultipartUpload'
- 's3:PutObjectRetention'
- 's3:GetObjectVersionAcl'
- 's3:GetObjectTagging'
- 's3:PutObjectTagging'
- 's3:DeleteObject'
- 's3:PutObjectAcl'
- 's3:GetObjectVersion'
Resource: !Sub
- '${ARN}/*'
- ARN:
Fn::ImportValue: !Sub ${Environment}:S3:Arn
According to the documentation it should be possible, but unfortunately I always get an error message
Template contains errors.: [/Resources/IAMRole/Type/Policies/0/PolicyDocument/Statement/0/Resource/Fn::Sub/1/ARN] 'null' values are not allowed in templates
How could the UseCase work?
There is a space issue in the Resource section.
Resource: !Sub
- '${ARN}/*'
- ARN:
Fn::ImportValue: !Sub ${Environment}:S3:Arn
It should be
Resource: !Sub
- '${ARN}/*'
- ARN:
Fn::ImportValue: !Sub ${Environment}:S3:Arn
Note: Fn starts under N of ARN instead of A.
Explanation: With the first indentation the line with Fn::ImportValue is considered as an input for !Sub, with the second indentation it becomes the value for ARN: defined the line above it.
Side note: Use 2 spaces or 4 spaces or tabs uniformly throughout the template.
In cloud-trail, I can select the existing log group CloudTrail/DefaultLogGroup under CloudWatch Logs section. Is it possible to complete this step using cloudformation Template?
Assuming you are creating the log group with CloudFormation as well:
LogGroup: # A new log group
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 365 # optional
CloudTrailLogsRole: # A role for your trail
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Version: '2012-10-17'
CloudTrailLogsPolicy: # The policy for your role
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- logs:PutLogEvents
- logs:CreateLogStream
Effect: Allow
Resource:
Fn::GetAtt:
- LogGroup
- Arn
Version: '2012-10-17'
PolicyName: DefaultPolicy
Roles:
- Ref: CloudTrailLogsRole
CloudTrail: # The trail
Type: AWS::CloudTrail::Trail
Properties:
IsLogging: true
CloudWatchLogsLogGroupArn:
Fn::GetAtt:
- LogGroup
- Arn
CloudWatchLogsRoleArn:
Fn::GetAtt:
- CloudTrailLogsRole
- Arn
DependsOn:
- CloudTrailLogsPolicy
- CloudTrailLogsRole
If using an existing log group:
CloudTrailLogsRole: # A role for your trail
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Version: '2012-10-17'
CloudTrailLogsPolicy: # The policy for your role
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- logs:PutLogEvents
- logs:CreateLogStream
Effect: Allow
Resource: <your existing log group arn here>
Version: '2012-10-17'
PolicyName: DefaultPolicy
Roles:
- Ref: CloudTrailLogsRole
CloudTrail: # The trail
Type: AWS::CloudTrail::Trail
Properties:
IsLogging: true
CloudWatchLogsLogGroupArn: <your existing log group arn here>
CloudWatchLogsRoleArn:
Fn::GetAtt:
- CloudTrailLogsRole
- Arn
DependsOn:
- CloudTrailLogsPolicy
- CloudTrailLogsRole
I have a IAM policy which fails to deploy using the Serverless Framework. The error message is (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument;). The policy looks like this:
DtcServiceFunctionRole:
Type: AWS::IAM::Role
Properties:
Path: "/"
RoleName: DtcServiceFunctionRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: dtc-invoke-policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "lambda:InvokeFunction"
Resource:
- "arn:aws:lambda:us-east-1:xxxxxxxxxxxxx:function:NotificationServiceFunction"
- PolicyName: dtc-dynamodb-policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "dynamodb:BatchGetItem"
- "dynamodb:BatchWriteItem"
- "dynamodb:DeleteItem"
- "dynamodb:GetItem"
- "dynamodb:PutItem"
- "dynamodb:Query"
- "dynamodb:Scan"
- "dynamodb:UpdateItem"
Resource:
- "arn:aws:dynamodb:us-east-1:xxxxxxxxxxxxx:table/VehicleDtcTable"
- "arn:aws:dynamodb:us-east-1:xxxxxxxxxxxxx:table/DtcTable"
- Effect: Allow
Any help to point me in the right direction is appreciated. Thanks.
It looks like your yaml is not correctly indented at :
Statement:
- Effect: Allow
Action:
- "dynamodb:BatchGetItem"
- "dynamodb:BatchWriteItem"
- "dynamodb:DeleteItem"
- "dynamodb:GetItem"
- "dynamodb:PutItem"
- "dynamodb:Query"
- "dynamodb:Scan"
- "dynamodb:UpdateItem"
it should be:
DtcServiceFunctionRole:
Type: AWS::IAM::Role
Properties:
Path: "/"
RoleName: DtcServiceFunctionRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: dtc-invoke-policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "lambda:InvokeFunction"
Resource:
- "arn:aws:lambda:us-east-1:xxxxxxxxxxxxx:function:NotificationServiceFunction"
- PolicyName: dtc-dynamodb-policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "dynamodb:BatchGetItem"
- "dynamodb:BatchWriteItem"
- "dynamodb:DeleteItem"
- "dynamodb:GetItem"
- "dynamodb:PutItem"
- "dynamodb:Query"
- "dynamodb:Scan"
- "dynamodb:UpdateItem"
Resource:
- "arn:aws:dynamodb:us-east-1:xxxxxxxxxxxxx:table/VehicleDtcTable"
- "arn:aws:dynamodb:us-east-1:xxxxxxxxxxxxx:table/DtcTable"
- Effect: Allow
I'm trying to get Cloudtrail on the road and want to set up a Cloudtrail s3bucket. but the Policy does not complete. Here is my code:
CloudtrailBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Delete
Description: Stores all Trails for this account
Properties:
AccessControl: BucketOwnerFullControl
BucketName: !Sub "${AWS::AccountId}-invoice-cloudtrail"
LifecycleConfiguration:
Rules:
- Id: GlacierRule
Prefix: glacier
Status: Enabled
ExpirationInDays: '365'
Transitions:
- TransitionInDays: '1'
StorageClass: Glacier
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
Tags:
- Key: Name
Value: !Sub '${EnvironmentName} ${Project}-CloudtrailBucket'
VersioningConfiguration:
Status: Suspended
and this is the Policy I want to use:
CloudtrailBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref CloudtrailBucket
PolicyDocument:
Statement:
- Sid: AWSCloudTrailAclCheck
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action:
- s3:GetBucket*
Resource:
- !Sub "arn:aws:s3:::${AWS::AccountId}-invoice-cloudtrail/*"
- Sid: AWSCloudTrailWrite
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action: s3:PutObject
Resource:
- !Sub "arn:aws:s3:::${AWS::AccountId}-invoice-cloudtrail/*"
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
I really dont know what might wrong. the error message is the following:
Action does not apply to any resource(s) in statement (Service: Amazon S3; Status Code: 400; Error Code: MalformedPolicy; Request ID: 7A458D04A5765AC6; S3 Extended Request ID: EYn2is5Oph1+pnZ0u+zEH067fWwD0fyq1+MRGRxJ1qT3WK+e1LFjhhE9fTLOFiBnhSzbItfdrz0=)
I believe you have to change your policy to match the following:
CloudtrailBucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref CloudtrailBucket
PolicyDocument:
Statement:
- Sid: AWSCloudTrailAclCheck
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action:
- s3:GetBucketAcl
Resource:
- !Sub "arn:aws:s3:::${AWS::AccountId}-invoice-cloudtrail"
- Sid: AWSCloudTrailWrite
Effect: Allow
Principal:
Service: cloudtrail.amazonaws.com
Action: s3:PutObject
Resource:
- !Sub "arn:aws:s3:::${AWS::AccountId}-invoice-cloudtrail/*"
Condition:
StringEquals:
s3:x-amz-acl: bucket-owner-full-control
The reasoning is that s3:GetBucket* expands to s3:GetBucketAcl, s3:GetBucketCORS, etc (all here), all of these expecting a bucket as resource, and you have provided many objects on your original policy.
So I've changed the resource (removed /*) and also cleaned the policy a bit, since CloudTrail should required only s3:GetBucketAcl.