AWS Cloudformation Error: Policy has invalid resource - aws-cloudformation

I need to create an S3 bucket with public access, but restrict that access to only a specific IP.
I generated a policy using the policy generator for S3 buckets and then adapted it to my template by referencing the name of the bucket; however, CloudFormation keeps giving a "Policy has invalid resource" error.
Below is the relevant portion of the CloudFormation template I am using. "FirstS3BucketName" is the a parameter.
FirstS3BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref FirstS3BucketName
PolicyDocument: |
{
"Id": "Policy1581542658034",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1581542655517",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::${FirstS3BucketName}/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "3.132.69.181/32"
}
},
"Principal": "*"
}
]
}

All you really need to do is add a !Sub on your PolicyDocument line. FYI, all that JSON can be turned into YAML as well.
FirstS3BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref FirstS3BucketName
PolicyDocument: !Sub |
{
"Id": "Policy1581542658034",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1581542655517",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::${FirstS3BucketName}/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "3.132.69.181/32"
}
},
"Principal": "*"
}
]
}

Related

KMS Key Policy wildcard principal

I have multiple IAM role (up to 100) required to use this KMS key.
Instead of listing all the IAM role in the KMS key policy. Is there any way I can wildcard or condition it?
{
"Sid": "Enable IAM Role",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxx:role/a1",
"AWS": "arn:aws:iam::xxxxxxxxxx:role/a2",
"AWS": "arn:aws:iam::xxxxxxxxxx:role/a3"
............
"AWS": "arn:aws:iam::xxxxxxxxxx:role/a100"
},
"Action": "kms:*",
"Resource": "*"
}
I tried using arn:aws:iam::xxxxxxxxxx:root or using condition with stringLike, sourceArn,"arn:aws:iam::xxxxxxxxxx:role/a*"
but none of them work.
Would like to ask around if there is any alternative instead of listing all the iam role down?
This will help you
{
"Sid": "Enable IAM Role",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "kms:*",
"Resource": "*",
"Condition": {
"ArnLike": {
"aws:PrincipalArn": "arn:aws:iam::xxxxxxxxxx:role/a1*"
}
}
}

Images hosted on S3 AWS are not displayed on Facebook [duplicate]

I have a bucket of user images on Amazon S3 and I would like to allow access only to my Facebook Messenger bot. It seemed like the best way to do this was to create a bucket policy with a condition that only allows referrals from a Facebook url. But this doesn't work - the images fail to load in the bot.
Here is the bucket policy I created (trying both facebook.com and graph.facebook.com):
{
"Version": "2012-10-17",
"Id": "Facebook referer policy",
"Statement": [
{
"Sid": "Allow get requests originating from Facebook Messenger",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://www.facebook.com/*",
"https://www.graph.facebook.com/*"
]
}
}
}
]
}
When I change the bucket policy back to public (as per below) then the images load fine so the problem must be an access one.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::my-bucket/*"
]
}
]
}
Anyone have any better solutions for how to do this?
Solved thanks to the comment above and the user agent documentation from Facebook
The working bucket policy is this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringLike": {
"aws:UserAgent": [
"facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)",
"facebookexternalhit/1.1",
"Facebot"
]
}
}
}
]
}

Permission denied when aws_s3.executing table_import_from_s3 in postgresql database

I am getting this error when executing below query:
" ERROR: HTTP 403. Permission denied. Check bucket or provided credentials as they may no longer be valid."
SELECT aws_s3.table_import_from_s3(
'test',
'a,b,c,d,e',
'(format csv)',
'my-bucket-info',
'outer/inner/Inbound/sample.csv',
'us-east-1'
);
Bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123213213:role/abc-www-role"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket-info/*",
"arn:aws:s3:::my-bucket-info"
]
}
]
}
can anyone help?
Instead of using "s3:*" as action parameter use only * i.e.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123213213:role/abc-www-role"
},
"Action": "*",
"Resource": [
"arn:aws:s3:::my-bucket-info/*",
"arn:aws:s3:::my-bucket-info"
]
}
]
}

Cloudformation to covert string into list on apigateway policy document with condition

Below is the my cloudformation template. I want to convert aws:SourceVpc into list in the resource policy document. I tried with spilt but cft below error.
Invalid policy document. Please check the policy syntax and ensure that Principals are valid. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: xxxxx; Proxy: null)
Also devl and sdbx have 1 value where as others acnt and acpt have two values in mappings how can do it. Please suggest.
Output should like below.
aws:SourceVpc: ["vpc-7830jkd", "vpc-a1236"]
Mappings:
vpcid:
us-east-1:
sdbx: "vpc-1234"
devl: "vpc-2345"
acpt: "vpc-7830jkd,vpc-a1236"
us-east-2:
acnt: "vpc-a1236,vpc-7830jkd"
Parameters:
Env:
Type: String
Resources:
apigateway:
Type: "AWS::ApiGateway::RestApi"
Properties:
Name: mygateway
EndpointConfiguration:
Types:
- "PRIVATE"
Policy: !Sub
- |-
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": [
"execute-api:/*"
]
},
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": [
"execute-api:/*"
],
"Condition": {
"StringNotEquals": {
"aws:SourceVpc": !Split ["," , "${myappid}"]
}
}
}
]
}
- { myappid: !FindInMap [ vpcid, !Ref "AWS::Region", !Ref "Env" ] }
Output should like below. aws:SourceVpc: ["vpc-7830jkd", "vpc-a1236"]
Sadly, you can't do this. CFN is very limited in what it can do, and what you want is simply not achievable with plain CFN. You have to modify your Maps and provide all the vpc ids individually, not mix lists with individual values.
The other way would be through development of CFN macro or custom resource.

Allowing an Ionic app access a s3 bucket with Bucket Policy

I have a web application who gets videos from an s3 bucket. That bucket has a policy to only allow the access from certain domains. I now need an ionic app to access the same bucket, is there any way I can add this option to the policy?
Here is the policy as I have it now
{
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests originating from www.example.com.",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*.mp4",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"https://www.example.com/*"
]
}
}
}
]
}
I've tried adding file://* to the urls array but won't work.
You can use User-Agent to identify request coming from your app.
Here is code for the Bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*.mp4",
"Condition": {
"StringLike": {
"aws:UserAgent": "*Any name"
}
}
}
]
}
Also you have to add in your config.xml
<preference name="AppendUserAgent" value="Any name" />