This Terraform script provisions an S3 bucket and a CloudFront distribution in your AWS account for media hosting. The solution supports two access methods: Public and Signed URLs. You can store and access media files based on your access requirements, ensuring secure and efficient media delivery.
- This script effectively creates two AWS resources: an S3 bucket and a CloudFront distribution.
- Both may incur costs
- The cost is same as if you would create these resources manually
- This solution does not handle media optimization.
- Setup Terraform CLI
- A/ Use Terraform Cloud to store the infrastructure state
- Create Terraform Account
- Create Terraform Organization
- Name of the organization must match the name specified in
backend.tf
- feel free to rename it - Workspace will be automatically created based on
backend.tf
- Name of the organization must match the name specified in
- B/ Use local backend to store the infrastructure state
- Setup local backend
- A/ Use Terraform Cloud to store the infrastructure state
- Setup AWS CLI
- Create and upload SSH key to sign urls
- Add Key Group vars
- Go to AWS CloudFront key groups
- Copy id of the key group you previously created
- Create test.tfvars / production.tfvars file and set
cloudfront_key_group_id
value
- (optional) Feel free to change project_name in variables.tf, "pmh-origin" in main.tf and "pmh" prefix use for service naming
- Clone the repository to your local environment
- Navigate to the project directory
- Initialize the project by running the following command
terraform init
- Provision the infrastructure by running
terraform apply -var-file="testing.tfvars
Use the following commands to manage your Terraform infrastructure:
-
Initialize the project:
terraform init
-
Apply the configuration to create resources:
terraform apply -var-file="testing.tfvars
-
Destroy the infrastructure:
terraform destroy
The media hosting solution can be utilized in two distinct ways:
Public files are stored in the assets
folder within the S3 bucket, accessible via a direct URL generated from the
CloudFront distribution.
Steps to Access Public Files:
- Upload the media file to the
assets
folder in the S3 bucket. - Access the file by combining the CloudFront distribution URL with the media file path in S3:
https://<cloudfront_distribution_domain>/assets/<path_to_file>
- Replace
<cloudfront_distribution_domain>
with the actual CloudFront distribution domain, and<path_to_file>
with the path of the media file in theassets
folder.
- Replace
Files outside the assets
folder require a signed URL for access, providing an extra layer of security. Signed URLs can
be generated programmatically using the AWS SDK.
Example Signed URL Format:
https://<s3_bucket_name>.s3.<region>.amazonaws.com/<path_to_file>?X-Amz-Algorithm=<algorithm>&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=<credential>&X-Amz-Date=<date>&X-Amz-Expires=<expires>&X-Amz-Signature=<signature>&X-Amz-SignedHeaders=host&x-id=GetObject
Steps to Access Files Using Signed URLs:
- Generate a signed URL using the AWS SDK.
- (Optional) Store the signed URL in a database for future access.
- Use the signed URL to securely load the media file.
- Only files in the
assets
folder are publicly accessible; all other files require signed URLs. - Ensure that sensitive information, like AWS credentials, is handled securely.
- Look up tf documentation for more information about S3 and ClodFront modules configuration (especially expiration times).
- CloudFront cache invalidation:
- Go to
AWS -> CloudFront -> Distributions -> Invalidations
- Click
Create invalidation
button - Enter object path (wildcards can be used)
- Go to