I am creating a cloudformation stack where the templates creates Cloud trail and then S3 bucket and pushes all logs to S3 bucket.
I have tried creating Cloud trail,s3 bucket and tried attaching the s3 Bucket Policy to the bucket
Parameters:
loggroupname:
Type: String
trailname:
Type: String
s3bucketname:
Type: String
Resources:
createloggroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub ${loggroupname}
creates3bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub ${s3bucketname}
s3bucketpolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Sub ${s3bucketname}
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: 'AWSCloudTrailAclCheck20150319'
Effect: 'Allow'
Principal:
Service: 'cloudtrail.amazonaws.com'
Action: 's3:GetBucketAcl'
Resource:
!Sub 'arn:aws:s3:::${s3bucketname}'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: AWSCloudTrailWrite20150319
Effect: 'Allow'
Principal:
Service: 'cloudtrail.amazonaws.com'
Action: 's3:PutObject'
Resource:
!Sub 'arn:aws:s3:::${s3bucketname}/AWSLogs/${AWS::AccountId}/*'
Condition:
StringsEquals:
s3:x-amz-acl: 'bucket-owner-full-control'
myvpctrail:
DependsOn:
- s3bucketpolicy
Type: AWS::CloudTrail::Trail
Properties:
IsLogging: true
IsMultiRegionTrail: true
IncludeGlobalServiceEvents: true
S3BucketName: !Ref creates3bucket
Invalid Condition type : StringsEquals (Service: Amazon S3; Status Code: 400; Error Code: MalformedPolicy; Request ID: F7439B111E82A3FA; S3 Extended Request ID: IGU1L7BB77WcrhPtmydd5j6viQdMK0vqA3Qo4RTS209FAvjT3q6wBIsyabdt5B7pBFvdr2MT+sM=)
Simple typo.
It's StringEquals not StringsEquals.
Source: https://docs.aws.amazon.com/AmazonS3/latest/dev/amazon-s3-policy-keys.html
Related
I am trying to build s3 event application by referring the environment variable defined.
Below the template i am referring
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
CreateThumbnail:
Type: AWS::Serverless::Function
Properties:
Handler: handler
Runtime: runtime
Timeout: 60
Policies: AWSLambdaExecute
Environment:
Variables:
BUCKET_NAME: !Sub "${S3}"
Events:
CreateThumbnailEvent:
Type: S3
Properties:
Bucket: ""How can refer the s3 bucket form the environment here"
Events: s3:ObjectCreated:*
i actually need to refer the 'BUCKET NAME' from the 'Environment variable' and also need to add event trigger from the same s3.
can anyone help on this?
Thanks
There are two options,
Either you have defined the S3 bucket in the same template, and then you can reference it using the logical CFN ID:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-bucket-name
CreateThumbnail:
Type: AWS::Serverless::Function
Properties:
Handler: handler
Runtime: runtime
Timeout: 60
Policies: AWSLambdaExecute
Environment:
Variables:
BUCKET_NAME: !Ref S3Bucket
Events:
CreateThumbnailEvent:
Type: S3
Properties:
Bucket: !Ref S3Bucket
Events: s3:ObjectCreated:*
Or you do not have it defined in the same template, in which case you have to pass it to the stack as a parameter during deployment like this:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters:
S3Bucket:
Description: Name of the S3 Bucket
Type: String
Resources:
CreateThumbnail:
Type: AWS::Serverless::Function
Properties:
Handler: handler
Runtime: runtime
Timeout: 60
Policies: AWSLambdaExecute
Environment:
Variables:
BUCKET_NAME: !Ref S3Bucket
Events:
CreateThumbnailEvent:
Type: S3
Properties:
Bucket: !Ref S3Bucket
Events: s3:ObjectCreated:*
I am creating an S3 bucket in a SAM template and would like to give it public read access. This is what I came up with so far:
ProductBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub ${ProductBucketName}${Stage}
ProductBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref ProductBucket
PolicyDocument:
Id: PublicReadPolicy
Version: 2012-10-17
Statement:
- Sid: PublicReadForGetBucketObjects
Effect: Allow
Principal: '*'
Action: 's3:GetObject'
Resource: !Join
- ''
- - 'arn:aws:s3:::'
- !Ref ProductBucket
This fails with a malformed exception.
Your template is fine except the line that says - - 'arn:aws:s3:::' where its malformed. Just a suggestion that you can use Fn::Sub over Fn::Join when delimiter is an empty string.
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
ProductBucketName:
Type: String
Resources:
ProductBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub ${ProductBucketName}-${AWS::StackName}
ProductBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref ProductBucket
PolicyDocument:
Id: PublicReadPolicy
Version: 2012-10-17
Statement:
- Sid: PublicReadForGetBucketObjects
Effect: Allow
Principal: '*'
Action: 's3:GetObject'
Resource: !Sub arn:aws:s3:::${ProductBucket}/*
Hope this help you move forward.
I found the AWS documentation's yaml example to look a bit funny, but I followed it and gave my CF stack IAM s3:PutBucketPolicy permissions, and it worked. Below is my SAM.
ExampleBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub <bucket-name>
ExampleBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: "ExampleBucket"
PolicyDocument:
Statement:
- Action:
- "s3:GetObject"
Effect: "Allow"
Resource:
Fn::Join:
- ""
- - "arn:aws:s3:::"
- Ref: "ExampleBucket"
- "/*"
Principal: "*"
Here is the AWS documentation page you've probably already consulted: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-policy.html.
I have defined an S3 bucket in my serverless.yml file as follows:
resources:
Resources:
nameOfS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.stage}-name-of-s3-bucket
AccessControl: Private
What I would like to do now is to reference the arn of the bucket in an IAM role which is also defined as a resource e.g.
resources:
Resources:
# s3 bucket definition removed for brevity
iamRoleName:
Type: AWS::IAM::Role
Properties:
RoleName: ${self:custom.stage}-iam-role-name
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: ${self:custom.stage}-iam-role-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "s3:PutObject"
Resource: *** Need the ARN of the s3 bucket here***
Is there a way to do this?
In my experience, the intrinsic functions in cloudformation work fine inside serverless.yml, but not the yaml short form.
i.e. use Fn::GetAtt over !GetAtt
As long as you use the full syntax for yaml, it should work.
Try this (untested)
resources:
Resources:
nameOfS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.stage}-name-of-s3-bucket
AccessControl: Private
iamRoleName:
Type: AWS::IAM::Role
Properties:
RoleName: ${self:custom.stage}-iam-role-name
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: ${self:custom.stage}-iam-role-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "s3:PutObject"
Resource:
"Fn::GetAtt": [ nameOfS3Bucket, Arn ]
I need some help writing the cloud formation that would get triggered by S3 put, from reading the documentation I see that you need NotificationConfiguration with event and function specified in bucket definition, but I keep getting the error " Unable to validate the following destination configurations" and it craps out and rollback the update. Can someone take a look at my CF script and identify what I am doing wrong, I think the issue could be in either NotificationConfiguration or rLambdaInvokePermission, but I am not sure which much appreciated!
here's my yaml:
Resources:
rAppBucketS3Policy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref rS3bucket
PolicyDocument:
Statement:
# SSL access enforced
- Sid: EnforceSecureTransport
Action: s3:*
Effect: Deny
Principal: '*'
Resource: !Join ["",[ "arn:aws:s3:::", Ref: rS3bucket, '/*' ] ]
Condition:
Bool:
aws:SecureTransport: 'false'
- Sid: EnforceEncryptionOnPut
Effect: Deny
Principal: '*'
Action: s3:PutObject
Resource: !Join ["",[ "arn:aws:s3:::", Ref: rS3bucket, '/*' ] ]
Condition:
StringNotEquals:
s3:x-amz-server-side-encryption: AES256
rLambdaInvokePermission:
#DependsOn: "int1-draps-us-east-1"
Type: AWS::Lambda::Permission
Properties:
FunctionName: us-east-1-upload
#FunctionName: !GetAtt rUploadLambda.Arn
Action: lambda:InvokeFunction
Principal: s3.amazonaws.com
SourceArn: !GetAtt rS3bucket.Arn
rS3bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
BucketName: !Sub ${pAWSAccountLC}-${pParentVPCLC}-${pAppNameLC}-${AWS::Region}
CorsConfiguration:
CorsRules:
- AllowedHeaders: [ChecksumValue, CheckDate]
AllowedMethods: [GET, PUT, POST, DELETE]
ExposedHeaders: [ChecksumValue, CheckDate]
AllowedOrigins: ['*']
LifecycleConfiguration:
Rules:
- Id: Transition1day
Status: Enabled
Transitions:
- TransitionInDays: !Ref pS3GLACIERTransitionPeriod
StorageClass: GLACIER
**NotificationConfiguration:
LambdaConfigurations:
-
Event: "s3:ObjectCreated:*"
Function:
Fn::ImportValue:
Fn::Sub: "us-east-1-upload-rUploadLambda"**
Cloud forming an S3 bucket with user, user access keys, and policy. It should create the stack and output the user access keys needed to work with the created S3 bucket via the SDK. Bucket Policy gets stuck in the CREATING phase forever when trying to reference the BucketUser ARN in the BucketPolicy Principal.
CloudFormation is successful with
BucketPolicy: ... Principal: "*"
But BucketPolicy resource is stuck in CREATE forever with
BucketPolicy: ... Principal: !GetAtt BucketUser.Arn
This successfully returns the BucketUser.Arn when BucketPolicy: ... Principal: "*"
Outputs:
BucketUserArn:
Value: !GetAtt BucketUser.Arn
Desired Template:
AWSTemplateFormatVersion: "2010-09-09"
Description: "Creates bucket with bucket policy"
#Metadata:
Parameters:
app:
Type: String
Description: (required) Application name (Also used for bucket name. Follow S3 bucket name conventions)
Default: ymessage-bucket-test
Resources:
BucketUser:
Type: "AWS::IAM::User"
Properties:
UserName: !Ref app
UserAccessKey:
Type: "AWS::IAM::AccessKey"
Properties:
Status: Active
UserName: !Ref app
DependsOn: BucketUser
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref app
BucketPolicy:
Type: "AWS::S3::BucketPolicy"
Properties:
Bucket: !Ref app
PolicyDocument:
Statement:
-
Action:
- "s3:*"
Effect: "Allow"
Resource:
Fn::Join:
- ""
-
- "arn:aws:s3:::"
- !Ref app
- "/*"
Principal: !GetAtt BucketUser.Arn
DependsOn: BucketUser
Outputs:
AccessKeyId:
Value: !Ref UserAccessKey
AccessKeySecret:
Value: !GetAtt UserAccessKey.SecretAccessKey
BucketURL:
Value: !GetAtt Bucket.WebsiteURL
BucketUserArn:
Value: !GetAtt BucketUser.Arn
Working Template:
AWSTemplateFormatVersion: "2010-09-09"
Description: "Creates bucket with bucket policy"
#Metadata:
Parameters:
app:
Type: String
Description: (required) Application name (Also used for bucket name. Follow S3 bucket name conventions)
Default: ymessage-bucket-test
Resources:
BucketUser:
Type: "AWS::IAM::User"
Properties:
UserName: !Ref app
UserAccessKey:
Type: "AWS::IAM::AccessKey"
Properties:
Status: Active
UserName: !Ref app
DependsOn: BucketUser
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref app
BucketPolicy:
Type: "AWS::S3::BucketPolicy"
Properties:
Bucket: !Ref app
PolicyDocument:
Statement:
-
Action:
- "s3:*"
Effect: "Allow"
Resource:
Fn::Join:
- ""
-
- "arn:aws:s3:::"
- !Ref app
- "/*"
Principal: "*"
DependsOn: BucketUser
Outputs:
AccessKeyId:
Value: !Ref UserAccessKey
AccessKeySecret:
Value: !GetAtt UserAccessKey.SecretAccessKey
BucketURL:
Value: !GetAtt Bucket.WebsiteURL
BucketUserArn:
Value: !GetAtt BucketUser.Arn
Found the issue: In the BucketPolicy it can directly accept Principal: "*" but if you want to use an arn do this:
Principal:
AWS:
- !GetAtt BucketUser.Arn