.
├── modules
│ ├── aws_cloudfront_distribution
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── aws_s3_bucket
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ └── static_site
│ ├── main.tf
│ ├── outputs.tf
│ ├── providers.tf
│ └── variables.tf
├── backend.tf
├── static_sites.tf
├── outputs.tf
├── README.md
└── variables.tf
Name | Version |
---|---|
terraform | >= 1.6.4 |
- HTTP Remote state store for backend
- AWS account
Name | Version |
---|---|
aws | >= 5.29.0 |
Local module to create static sites with all their necessary resources
./modules/static-sites
Called by main module
Name | Description | Type | Default | Required |
---|---|---|---|---|
static_sites | Static Sites | string |
N/A |
yes |
environment | System environment | string |
N/A |
yes |
additional_tags | Additional resource tags | map(string) |
null |
no |
Local module to create and configure CloudFront Distributions
./modules/aws_cloudfront_distribution
Called by static-site module
Name | Description | Type | Default | Required |
---|---|---|---|---|
environment | System environment (dev, staging, prd) | string |
N/A |
yes |
path | Path pattern | string |
N/A |
yes |
enabled | Whether if the CF distribution is enabled or not | bool |
true |
no |
is_ipv6_enabled | Whether if IPv6 enabled or not | bool |
true |
no |
default_root_object | File name of the default root object | string |
"index.html" |
no |
price_class | Price class for this distribution. | string |
"PriceClass_100" |
no |
aliases | List of domain aliases | list(string) |
null |
no |
origins | CloudFront origins | map(object) |
{} |
no |
default_cache_behavior | Default cache behaviour settings | object |
N/A |
yes |
cache_behaviours | Ordered cache behaviours | list(object) |
[] |
no |
geo_restriction_type | Method that you want to use to restrict distribution of your content | string |
"none" |
no |
geo_restriction_locations | ISO 3166-1-alpha-2 codes for which you want CloudFront either to distribute your content (whitelist) or not distribute your content (blacklist) | list(string) |
[] |
no |
minimum_protocol_version | Minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections | string |
"TLSv1.2_2021" |
no |
bucket_id | S3 Bucket ID | string |
N/A |
yes |
bucket_arn | S3 Bucket ARN | string |
N/A |
yes |
Local module to create and configure S3 Buckets
./modules/aws_s3_bucket
Called by static-site module
Name | Description | Type | Default | Required |
---|---|---|---|---|
environment | System environment (dev, staging, prd) | string |
N/A |
yes |
bucket_name | Name of the S3 bucket | string |
N/A |
yes |
force_destroy | If the service needs to be exposed | boolean |
false |
no |
object_lock_enabled | Whether object block is enabled or not | bool |
false |
no |
bucket_accelerate_status | Transfer acceleration state of the bucket | string |
"Suspended" |
no |
expected_bucket_owner | Account ID of the expected bucket owner | string |
null |
no |
block_public_acls | Whether to block public ACLs | bool |
true |
no |
block_public_policy | Whether to block public policy | bool |
true |
no |
ignore_public_acls | Whether to ignore public ACLs | bool |
true |
no |
restrict_public_buckets | Whether to restrict public buckets | bool |
true |
no |
bucket_acl | The canned ACL to apply | string |
"private" |
no |
object_ownership | Object ownership | string |
"BucketOwnerPreferred" |
no |
versioning_enabled | Versioning state of the bucket | string |
"Enabled" |
no |
s3_objects | S3 objects to upload into the bucket | map(object) |
{} |
no |
- TF_HTTP_ADDRESS - Address of the state store
- TF_VAR_environment - System environment to deploy/manage (dev, staging, prod)
!Important notes!
Highly advised to use separate state stores per environment to lower blast radius
To add a new URI with dedicated CF and S3, add the corresponding code to the static_sites.tf
Replace the '#' with actual number and 'uri_path' with URI like /path
uri_path = {
site_number = #
}
The code has been designed to be modular for easy change and extension, the 2 different resource types have their own modules prepared.
- Small modules have been written to make it possible to make changes to every related environment/cf/s3 centrally. So after a change, a re-deployment picks the changes up everywhere
- A wrapper module has been written to reduce code duplication and make the usage easier (static-site module)
- As many options got a default value as possible in order to make it easier to add new setups, and reduce code duplication
- Deployments are prepared to be separated by environment
The necessary setting and policies/attachments, access control resources are all managed in the respective modules
- The code can be integrated into a CI/CD pipeline by running Terraform for each environment by child pipelines and, storing the states in a remote store relying on TF_VAR_environment environmental variable With this, changes can be deployed to respective environments separately, without affecting other environments, so every change can go through the full deployment cycle
- Add terraform fmt to the pipeline to ensure code quality
- Better way to make the pipeline pull always up-to-date modules from an external source rather than using internal modules
- Apply human friendly DNS name for the CloudFront endpoints with AWS-managed SSL certificates
- Use only 1 CloudFront distribution and S3 bucket per environment for simplicity and cost savings
- Replace site_number with generated value