!Sub. Follow the examples and adapt names/values to your environment.
Open the CloudFormation stack where you’ll add the new resources.

Template skeleton
Here is a compact example of the top-level sections (Mappings, Parameters). Use these as a starting point and update parameter names and mapping values to match your environment.Create the S3 bucket resource
Add an S3 bucket resource (if you don’t already have one). This example demonstrates using parameters and mappings for Tags:Add the bucket policy resource
Add a BucketPolicy resource (logical name:MyPublicReadPolicy) and set the policy to allow s3:GetObject for all objects in the bucket.
Policy field summary
| Field | Purpose | Notes |
|---|---|---|
| Bucket | Target bucket | Reference the bucket logical name or the actual bucket name (!Ref InputBucketName) |
| PolicyDocument.Version | Policy language version | Typically "2012-10-17" |
| Statement.Effect | Allow or Deny | Use Allow to grant access |
| Statement.Principal | Who the statement applies to | "*" makes the statement public (everyone) |
| Statement.Action | Allowed actions | s3:GetObject allows reads of objects |
| Statement.Resource | Resource ARNs targeted by the statement | Use arn:aws:s3:::bucket-name/* to match all objects in the bucket |
arn:aws:s3:::your-bucket-name — to target all objects add /*.

Option 1 — Manual ARN (copy from console)
Replace the Resource value with the bucket ARN you copied from the console and append/* to include all objects:
Option 2 — Template-driven ARN (recommended)
Construct the ARN dynamically with the!Sub intrinsic function. This avoids hard-coded names and keeps the template reusable:
InputBucketName.
Public access to objects depends on both the bucket policy and S3 public access block settings (account-level and bucket-level). If objects remain inaccessible after deploying a public-read policy, verify your S3 Public Access Block configuration in the AWS Console or via the API.
Next steps and best practices
- Restrict access to specific principals (IAM users, roles, or AWS accounts) instead of using
"*"when possible. - Use Conditions to limit access by IP range, referer, or secure transport (e.g.,
"Bool": {"aws:SecureTransport": "true"}). - Consider using presigned URLs or CloudFront signed URLs for controlled public distribution of objects.
Links and references
- AWS CloudFormation Documentation
- Amazon S3 Documentation
- AWS IAM JSON Policy Elements: Principal
- CloudFormation intrinsic function !Sub