In this module, you will create an S3 bucket that will store your web files. Later you will convert this bucket into a static-hosted website. Let's get started!
Create a new branch in GitHub
Login to GitHub
Select the Issues tab > Select New Issue
Add the a title, e.g. Create S3 Bucket
Select Submit new issue
On the right pane, under Development, Select Create a branch
Leave the defaults > Select Create branch
Open your IDE Terminal.
Input the following:
git fetch origin
git checkout YOUR_BRANCH_NAME
Modifying s3 files
main.tf
In your IDE, you will start by modifying the
./infra/modules/aws/s3/main.tf
Input the following to create an s3 bucket resource
resource "aws_s3_bucket" "bucket" { bucket = var.bucket_name tags = { Name = "${var.bucket_name}" } }
This will create a bucket with a name that will be defined at a later time. The purpose of utilizing variables is so that you can reuse this configuration file by supplying a
bucket_name
.
- Save the file
variables.tf
For
var.bucket_name
to be available for use, you have to define what the variable type is, e.g.string, number, map, object, etc.
Input the following:
variable "bucket_name" { description = "Given name of the S3 bucket" type = string }
Utilizing the
variable
block you are defining the input variable for bucket_name. The expected input will be a string value, e.g. "myveryuniquelynamedbucket".Note: S3 Bucket names must be globally unique.
- Save the file
outputs.tf
The
outputs.tf
is utilized for return variables. You can use these as references for other modules to utilize. These can also be return values to the terminal.Input the following for the S3 Bucket return values
output "id" { description = "Name of the bucket." value = aws_s3_bucket.bucket.id } output "arn" { description = "ARN of the bucket. Will be of format arn:aws:s3:::bucketname" value = aws_s3_bucket.bucket.arn } output "bucket_domain_name" { description = "Bucket domain name. Will be of format bucketname.s3.amazonaws.com." value = aws_s3_bucket.bucket.bucket_domain_name } output "bucket_regional_domain_name" { description = "Regional Domain Name for S3 Bucket" value = aws_s3_bucket.bucket.bucket_regional_domain_name }
Referencing the Terraform S3 reference, these are the valid outputs available for the S3 Bucket.
- Save the file
At this point you have almost all you need to create an S3 Bucket. You would just have to define what the bucket_name
is. However, in the next few sections I will be walking you through creating additional modules so that in the event you wanted to create another static s3 bucket website, or if you wanted to build a replica of the original architecture, you can utilize that same module by defining different input variables. Essentially future proofing so that you do not have rewrite the code to tie these resources together all over again.
Modifying s3_cloudfront_site files
In this section, you will prepare the S3 static website module. This will be the main module for creating the static hosting website configuration.
You will start with the main.tf
in ./infra/modules/s3_cloudfront_site
. This module will reference the ./infra/modules/aws/s3/main.tf
resource.
main.tf
In the
./infra/modules/s3_cloudfront_site/main.tf
, input the following:module "bucket" { source = "../aws/s3" bucket_name = var.bucket_name }
The module block references the child module in ../aws/s3. This is the relative path to the current
main.tf
you are configuring.
bucket_name =
comes from thevar.bucket_name
in thes3/main.tf.
For consistency, you'll passvar.bucket_name
from this module to thes3/main.tf's var.bucket_name
. This way there is no confusion on where that variable is going.
- Save the file
variables.tf
Much like the
variables.tf
in the s3 folder, you will have to define what the input variable type is forvar.bucket_name
.In your
./infra/modules/s3_cloudfront_site/variables.tf
, input the following:variable "bucket_name" { description = "Given name of the S3 bucket" type = string }
Save the file
outputs.tf
Define the outputs for this module. Here, you will define the S3 Bucket resource's outputs from this module.
In your
./infra/modules/s3_cloudfront_site/outputs.tf
, input the following:output "bucket_id" { description = "Name of the bucket." value = module.bucket.id } output "bucket_arn" { description = "ARN of the bucket. Will be of format arn:aws:s3:::bucketname" value = module.bucket.arn } output "bucket_domain_name" { description = "Bucket domain name. Will be of format bucketname.s3.amazonaws.com." value = module.bucket.bucket_domain_name } output "bucket_regional_domain_name" { description = "Regional Domain Name for S3 Bucket" value = module.bucket.bucket_regional_domain_name }
The output variable names are different here because in the future, there will be other resources that have
id
andarn
values as well. To distinguish between where the value comes from it's good to give a unique identifier where the output is coming from.Note the values for the output variables. They reference the module in the main.tf.
- Save the file
Modifying my_portfolio files
main.tf
Similar to the s3_cloud_site module, you will modify the main, variables and outputs Terraform files. The my_portfolio module will be the main module to reference when tying all the associated services together, e.g. S3, CloudFront, DynamoDB, SNS, etc.
This module will reference the s3_cloudfront_site module to create the S3 bucket, and then later to create the CloudFront distribution.
In the
./infra/modules/my_portfolio/main.tf
, input the following:module "static_website" { source = "../s3_cloudfront_site" bucket_name = var.bucket_name }
Similar to the other main.tf files, you are passing the variable bucket name, and referencing the s3_cloudfront_site module.
- Save the file
variables.tf
In your
./infra/modules/my_portfolio/variables.tf
, input the following:variable "bucket_name" { description = "Given name of the S3 bucket" type = string }
- Save the file
outputs.tf
In your ./infra/modules/my_portfolio/outputs.tf
, input the following:
output "bucket_id" {
description = "Name of the bucket."
value = module.static_website.bucket_id
}
output "bucket_arn" {
description = "ARN of the bucket. Will be of format arn:aws:s3:::bucketname"
value = module.static_website.bucket_arn
}
output "bucket_domain_name" {
description = "Bucket domain name. Will be of format bucketname.s3.amazonaws.com."
value = module.static_website.bucket_domain_name
}
output "bucket_regional_domain_name" {
description = "Regional Domain Name for S3 Bucket"
value = module.static_website.bucket_regional_domain_name
}
- Save the file
Modifying /infra/main.tf
./infra/main.tf
will be the module where all variables will be defined. This module will reference the my_portfolio module.
main.tf
In your
./infra/main.tf
, input the following:module "my_static_website" { source = "./modules/my_portfolio" bucket_name = "Your_Unique_Bucket_Name" }
- Save the file
Since bucket_name is hard coded, you do not have to modify the variables.tf
outputs.tf
If you would like to see the values for your resource output in the Terraform Cloud outputs, include the following:
output "bucket_id" { description = "Name of the bucket." value = module.my_static_website.bucket_id } output "bucket_arn" { description = "ARN of the bucket. Will be of format arn:aws:s3:::bucketname" value = module.my_static_website.arn } output "bucket_domain_name" { description = "Bucket domain name. Will be of format bucketname.s3.amazonaws.com." value = module.my_static_website.bucket_domain_name } output "bucket_regional_domain_name" { description = "Regional Domain Name for S3 Bucket" value = module.my_static_website.bucket_regional_domain_name }
I'm not too concerned about receiving these outputs, so I will not include it in my configuration. The only required output for CloudFront Invalidation will be the CloudFront ID.
Modifying .yml files
Modify your
terraform-plan.yml
andterraform-apply_cloudfront-invalidation.yml
Uncomment the
on:
arguments in each
Pushing to GitHub
Ensure your files are saved.
In your IDE Terminal, type the following:
git add .
Add all files that were changed.
git commit -m "modified modules to create S3 bucket"
Commit the changes with a comment.
git push
Push to GitHub.
Create Pull Request
Login to GitHub.
You should see the push on your repository.
Select Compare and pull request.
Validate the changes that were made to be pushed to
main
Select Create pull request.
Your Terraform Plan should run before you can merge to main
.
Select Merge pull request > Confirm merge.
Delete branch.
In your IDE Terminal, type the following:
git checkout main
git pull
Validation:
There are 2 ways for validation:
AWS CLI:
aws s3 ls michaelmaratita-static-website-tutorial
AWS Management Console:
- In the Search bar, search for "s3" > Select "Buckets"
You have completed this section on creating an S3 bucket. In the next module, you will upload your site files to your S3 bucket.