Skip to content

Commit

Permalink
refa: introduce multi-environment lab (#8)
Browse files Browse the repository at this point in the history
* refa: introduce multi-environment lab

* refa: improve wording
  • Loading branch information
HenrikFricke authored May 20, 2022
1 parent 8dd8c5a commit aaabca7
Show file tree
Hide file tree
Showing 55 changed files with 578 additions and 223 deletions.
2 changes: 1 addition & 1 deletion 1-getting-started/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,4 @@ You might have noticed the manual creation of the S3 bucket. To keep it simple f

## Next

That’s it for the first lab. We learned more about the Terraform Language (provider, data sources, resources and outputs) and deployed some AWS resources. In the [next lab](../2-modules/), we extend the stack and use a third-party module.
That’s it for the first lab. We learned more about the Terraform Language (provider, data sources, resources and outputs) and deployed some AWS resources. In the [next lab](../2-third-party/), we extend the stack and use a third-party module.
File renamed without changes.
2 changes: 1 addition & 1 deletion 2-modules/README.md → 2-third-party/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,4 @@ Okay, nothing really special here. We extended the stack and introduced more res

## Next

The [next lab](../3-composition/) covers a very important topic: Instead of just deploying the stack once, we want to deploy the stack for multiple environments (e.g. staging and prod). Along the way, we discuss module composition and code splitting.
The [next lab](../3-module-composition/) covers a very important topic: Instead of just deploying the stack once, we want to deploy the stack for multiple environments (e.g. staging and prod). Along the way, we discuss module composition and code splitting.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
218 changes: 0 additions & 218 deletions 3-composition/README.md

This file was deleted.

File renamed without changes.
146 changes: 146 additions & 0 deletions 3-module-composition/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Module Composition

The previous lab introduced a third-party module to easily deploy a Lambda function with multiple resources. In this lab, we want to improve the growing codebase and create custom modules for the static website and the API.

## Custom Modules

1. Create new folders:
```sh
mkdir modules
mkdir modules/api
mkdir modules/website
```
3. Move the `functions` folder inside the `modules/api` folder:
```sh
mv functions modules/api
```
4. Move the `index.html` file inside the `modules/website` folder:
```sh
mv index.html modules/website
```
5. Create a `main.tf` file inside the `modules/api` folder:
```sh
touch modules/api/main.tf
```
6. Add the following lines to the file:
```tf
module "lambda_function" {
source = "terraform-aws-modules/lambda/aws"
version = "3.2.0"
function_name = "hello-world"
handler = "helloworld.handler"
runtime = "nodejs14.x"
source_path = "${path.module}/functions"
publish = true
allowed_triggers = {
AllowExecutionFromAPIGateway = {
service = "apigateway"
source_arn = "${aws_apigatewayv2_api.hello_world.execution_arn}/*/*"
}
}
}
resource "aws_apigatewayv2_api" "hello_world" {
name = "hello-world"
protocol_type = "HTTP"
target = module.lambda_function.lambda_function_arn
}
```
7. Create a `outputs.tf` file inside the `modules/api` folder:
```sh
touch modules/api/outputs.tf
```
8. Add the following lines to the file:
```sh
output "url" {
description = "Hello World API URL"
value = aws_apigatewayv2_api.hello_world.api_endpoint
}
```
11. Create a `main.tf` file inside the `modules/website` folder:
```sh
touch modules/website/main.tf
```
12. Add the following lines to the file:
```tf
data "aws_caller_identity" "current" {}
resource "aws_s3_bucket" "website" {
bucket = "hello-world-website-${data.aws_caller_identity.current.account_id}"
force_destroy = true
}
resource "aws_s3_object" "startpage" {
bucket = aws_s3_bucket.website.id
key = "index.html"
source = "${path.module}/index.html"
acl = "public-read"
content_type = "text/html"
}
resource "aws_s3_bucket_website_configuration" "website" {
bucket = aws_s3_bucket.website.bucket
index_document {
suffix = "index.html"
}
}
```
13. Create a `outputs.tf` file inside the `modules/website` folder:
```sh
touch modules/website/outputs.tf
```
14. Add the following lines to the file:
```sh
output "url" {
description = "Hello World Website URL"
value = "http://${aws_s3_bucket_website_configuration.website.website_endpoint}"
}
```
17. Replace the root `main.tf` file:
```tf
terraform {
required_version = "~> 1.1.7"
backend "s3" {
key = "terraform.tfstate"
region = "eu-west-1"
}
}
provider "aws" {
region = "eu-west-1"
}
module "website" {
source = "./modules/website"
}
module "api" {
source = "./modules/api"
}
```
18. Replace the root `outputs.tf` file:
```tf
output "api_url" {
description = "Hello World API URL"
value = module.api.url
}
output "website_url" {
description = "Static Website URL"
value = module.website.url
}
```

Okay, that was a huge refactoring. Let's examine it and talk about it step-by-step.

First of all, we created our first custom modules. As you can see, it always follows the same pattern. We created new folders and added a `main.tf` and `outputs.tf` file. We then split up the root module into two custom modules. Finally, we introduced the custom modules in the root module and updated the output values to retrieve the data from the modules.

The modules follow a domain-driven approach. Instead of introducing one custom module, we separate the infrastructure by specific domains. In our case, we have dedicated modules for the API and static website hosting. Small and domain-driven modules make it easy to maintain the codebase and improve the readability for humans. Try not to overthink your custom modules and avoid complex branching logic or for loops.

## Next

The modules shaped reusable components. In the [next lab](../4-multi-environment/), we use the modules to set up a staging and production environment.
20 changes: 20 additions & 0 deletions 3-module-composition/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
terraform {
required_version = "~> 1.1.7"

backend "s3" {
key = "terraform.tfstate"
region = "eu-west-1"
}
}

provider "aws" {
region = "eu-west-1"
}

module "website" {
source = "./modules/website"
}

module "api" {
source = "./modules/api"
}
Loading

0 comments on commit aaabca7

Please sign in to comment.