Skip to content

savedra1/terraform-aws-simple-site

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simple site spin-up

This Terraform module allows you to easily spin up a static website hosted in AWS S3, served by AWS Cloudfront with TLS and www. support. If you choose to add a custom domain (managed by AWS Route 53), a hosted zone and ACM certification will be created and assigned.

The module is very easy to use and allows flexible configuration with optional inputs.

example

Usage

You will need the following before using this module:

  • AWS user credentials with the appropriate permissions
  • A directory containing the contents of your S3 bucket
  • (OPTIONAL) A Route53-managed custom domain if you wish to use your own domain. instructions for moving a domain to Route53 can be found here.
  • (OPTIONAL) A S3 log bucket if you intend to set up logging for your site.

Example with a custom domain

terraform {
  backend "s3" {
    bucket = "your-state-bucket"
    key    = "your/state-key/path"
    region = "your-aws-region"
  }
}

module "simple_site" {
    source           = "savedra1/simple-site/aws"
    version          = "0.0.6"
    aws_region       = "us-west-1"
    site_bucket      = "mysitebucketname.com"
    object_directory = "./example_objects"
    domain_name      = "mydomainname.com"
}

Example without custom domain

terraform {
  backend "s3" {
    bucket = "your-state-bucket"
    key    = "your/state-key/path"
    region = "your-aws-region"
  }
}

module "static_site" {
    source           = "savedra1/simple-site/aws"
    version          = "0.0.6"
    aws_region       = "us-west-1"
    site_bucket      = "mysitebucketname.com"
    object_directory = "./example_objects"
}

Example using all inputs

See All Inputs & Outputs

terraform {
  backend "s3" {
    bucket = "your-state-bucket"
    key    = "your/state-key/path"
    region = "your-aws-region"
  }
}

module "static_site" {
  source              = "savedra1/simple-site/aws"
  version             = "0.0.6"
  aws_region          = "us-west-1"
  site_bucket         = "mysitebucketname.com"
  object_directory    = "./example_objects"
  index_file_name     = "home.html"
  error_file_name     = "404.html"
  available_locations = ["US", "CA", "GB", "DE", "FR"]
  domain_name         = "example.com"
  domain_auto_renew   = true
  log_bucket          = "my-log-bucket"
  log_bucket_prefix   = "cloudfront-logs"
}

Example outputs

output "cloudfront_endpoint" {
    value = module.simple_site.cloudfront_endpoint
}

output "custom_endpoint" {
    value = module.simple_site.custom_endpoint 
}

All Inputs & Outputs

Inputs ⬅️

  • aws_region (REQUIRED) - The region to use for your AWS state management bucket and your site bucket in AWS S3.

  • site_bucket (REQUIRED) - The name of the S3 bucket used for hosting your static site.

  • object_directory (OPTIONAL) - The path for where the files are stored for your S3 bucket. This is always relative to the directory level from which terraform apply is ran. Default: ./

  • index_file_name (OPTIONAL) - The file name for the index document of the static site. Default: "index.html"

  • error_file_name (OPTIONAL) - The file name for the error document of the static site. Default: "error.html"

  • available_locations (OPTIONAL) - The default country codes to use for the CloudFront distribution. Default: [US, EU, CA]

  • domain_name (OPTIONAL) - The privately owned qualified domain name managed by Route53. Default: ""

  • domain_auto_renew (OPTIONAL) - Whether to assign auto-renewal to the managed Route53 domain. Default: True

  • log_bucket (OPTIONAL) - The name of your existing S3 bucket for storing server logs. Default: ""

  • log_bucket_prefix (OPTIONAL) - The name for the directory in which the logs are stored within your specified log bucket. Default: "simple-site-logs"

Outputs ➡️

  • cloudfront_endpoint - The unique web address generated by Cloudfront.

  • custom_endpoint - The custom web address provided by the user.

Permissions 🔐

Ensure the AWS user credentials used have the following permission scopes to allow all possible actions taken by this module:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*",
                "s3:CreateBucket",
                "s3:PutBucketTagging",
                "s3:DeleteBucket",
                "s3:DeleteBucketPolicy",
                "s3:DeleteObject",
                "s3:PutBucketVersioning",
                "s3:PutBucketPublicAccessBlock",
                "s3:PutBucketCORS",
                "s3:PutBucketWebsite",
                "s3:PutBucketRequestPayment",
                "s3:PutBucketLogging",
                "s3:PutBucketPolicy",
                "s3:PutObject",
                "s3:DeleteBucketWebsite",
                "s3:GetBucketAcl",
                "s3:PutBucketAcl",
                "s3:PutBucketOwnershipControls"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "route53:DeleteTrafficPolicy",
                "route53:CreateTrafficPolicy",
                "route53:GetHostedZone",
                "route53:DeleteCidrCollection",
                "route53:DeleteHostedZone",
                "route53:CreateCidrCollection",
                "route53:UpdateHostedZoneComment",
                "route53:DeleteTrafficPolicyInstance",
                "route53:CreateHostedZone",
                "route53:CreateReusableDelegationSet",
                "route53:CreateTrafficPolicyInstance",
                "route53:DeleteReusableDelegationSet",
                "route53:GetChange",
                "route53:ListTagsForResource",
                "route53domains:ListTagsForDomain",
                "route53domains:GetDomainDetail",
                "route53:ChangeResourceRecordSets",
                "route53domains:EnableDomainAutoRenew",
                "route53:ListResourceRecordSets",
                "route53domains:UpdateDomainNameservers",
                "route53domains:GetOperationDetail",
                "route53domains:DisableDomainAutoRenew"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "acm:DeleteCertificate",
                "acm:RequestCertificate",
                "acm:AddTagsToCertificate",
                "acm:DescribeCertificate",
                "acm:RemoveTagsFromCertificate",
                "acm:ListTagsForCertificate"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudfront:GetDistribution",
                "cloudfront:ListTagsForResource",
                "cloudfront:TagResource",
                "cloudfront:UpdateDistribution",
                "cloudfront:CreateDistribution",
                "cloudfront:DeleteDistribution",
                "cloudfront:CreateOriginAccessControl",
				"cloudfront:DeleteOriginAccessControl",
				"cloudfront:UpdateOriginAccessControl",
                "cloudfront:GetOriginAccessControl"
            ],
            "Resource": [
                "arn:aws:cloudfront::*:distribution/*",
                "arn:aws:cloudfront::*:origin-access-control/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:GenerateCredentialReport",
                "iam:GenerateServiceLastAccessedDetails",
                "iam:Get*",
                "iam:List*",
                "iam:SimulateCustomPolicy",
                "iam:SimulatePrincipalPolicy"
            ],
            "Resource": "*"
        }
    ]
}

Cost 💸

The only cost incurred from using this module would be from the Route53 Hosted Zone, created to validate an ACM certificate when a custom domain is used. The cost for this is $0.50 per month.

All other infrastructure falls within the AWS free tier. However, there could be some edge-case scenarios that cause additional costs. For more details of this please review the pricing documentation for s3, Cloudfront and Route53.

Contributing 🙏

Contributions to this project are welcome! If you have any improvement ideas feel free to raise an issue or fork the repo to send me a PR.