Terraform Multi-AZ Web Application Deployment Module for AWS
This terraform module deploys applications with an ALB, VPN, ECS Fargate Cluster, and an Aurora Cluster in multiple Availability Zones (AZs) on AWS.
DISCLAIMER: This module is for presentation purposes only and does not rely on any external terraform modules. It's not full-featured (e.g. HTTP only), and should not be used for production deployments.
Features
This module consists of the following parts:
- Application Load Balancer (ALB) for load balancing
- VPN for secure access to private resources
- ECS Fargate Cluster for running Docker containers
- Aurora Cluster for relational database storage
- Supports deployment in multiple availability zones
Architecture
Example
Review the ghost blog example to see how to use this module.
Usage
resource random_string database_password {
length = 41
special = false
}
module "multi_az_blog" {
source = "git::https://github.com/romcok/terraform-aws-ha-webapp.git"
name = "blog"
environment = "prod"
region = "us-east-1"
network = {
cidr_block = "10.0.0.0/16"
availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
private_subnet_cidrs = ["10.0.10.0/24", "10.0.20.0/24", "10.0.30.0/24"]
}
container = {
port = 2368
image = "ghost:latest"
env_vars = {
NODE_ENV = "production"
database__client = "mysql"
database__connection__host = "__DB_CLUSTER_ENDPOINT__"
database__connection__user = "__DB_USERNAME__"
database__connection__password = "__DB_PASSWORD__"
database__connection__database = "__DB_NAME__"
}
cpu = 512
memory = 1024
count = 3
volume_root = "/"
mount_paths = [ "/var/lib/ghost/content" ]
health_check_path = "/ghost/api/admin/site/"
}
database = {
engine = "mysql"
version = "8.0.mysql_aurora.3.03.0"
instance = "db.t4g.medium"
port = 3306
backup_retention_period = 7
skip_final_snapshot = true
username = "root"
password = random_string.database_password.result
}
vpn = {
enabled = true
cidr_block = "10.1.0.0/16"
server_private_key = file("./vpn-certs/server.key")
server_certificate = file("./vpn-certs/server.crt")
client_private_key = file("./vpn-certs/client.key")
client_certificate = file("./vpn-certs/client.crt")
certificate_authority = file("./vpn-certs/ca.crt")
}
}
Requirements
Name | Version |
---|---|
terraform | >= 1.4.4 |
aws | >= 4.62 |
Providers
Name | Version |
---|---|
aws | >= 4.62 |
Inputs
Name | Parameter | Description | Type |
---|---|---|---|
name | Module name | string |
|
environment | Environment (dev , prod ..) |
string |
|
region | Deployment region | string |
|
network | VPC network configuration | object |
|
cidr_block | VPC IPv4 CIDR block | network |
|
availability_zones | List of availability zones | list(string) |
|
public_subnet_cidrs | Public subnet IPv4 CIDR block per AZ | list(string) |
|
private_subnet_cidrs | Private subnet IPv4 CIDR block per AZ | list(string) |
|
container | ECS Fargate configuration | object |
|
port | Container port number | number |
|
image | Docker image | string |
|
env_vars | List of environment Variables | map(string) |
|
secrets | List of SSM paramaters | map(string) |
|
cpu | Task CPU allocation | number |
|
memory | Task memory allocation | number |
|
count | Number of desired tasks | number |
|
volume_root | EFS volume root path | string |
|
mount_paths | Container mapping paths | map(string) |
|
healt_check_path | Container health check path | string |
|
database | Database configuration | object |
|
username | Database username | string |
|
password | Databvase password | string |
|
engine | Aurora RDS engine (mysql or postgres ) |
string |
|
port | Database port (3306 for mysql ) |
number |
|
version | Aurora RDS version | string |
|
instance | Aurora RDS instance class | string |
|
backup_retention_period | Database backup retention period in days | number |
|
skip_final_snapshot | Indicates whether to skip the last snapshot before destruction | bool |
|
vpn | Client VPN configuration | object |
|
enabled | Indicates whether Client VPN service should be configured | bool |
|
cidr_block | Client VPN IPv4 CIDR block | string |
|
server_private_key | Server private key | string |
|
server_certificate | Server certificate | string |
|
client_private_key | Client private key | string |
|
client_certificate | Client certificate | string |
|
certificate_authority | Certificate authority | string |
Outputs
Name | Description |
---|---|
alb_dns_name | ALB dns name |
database_cluster_endpoint | Aurora cluster endpoint |
database_cluster_reader_endpoint | Aurora cluster reader endpoint |
database_endpoints | List of all aurora instance endpoints |
database_master_endpoint | Aurora cluster master instance endpoint |
database_read_replica_endpoints | List of aurora cluster read replica endpoints |
database_username | Database username |
database_name | Auora cluster database name |
volume_dns_name | EFS volume dns name |
volume_access_point_id | EFS volume access point id |
volume_mount_target_ips | ECS volume mount target IPv4 adresses |
vpn_id | ID of Client VPN endpoint |
vpn_arn | ARN of Client VPN endpoint |
vpn_dns_name | Client VPN DNS name |
ecs_cluster_name | ECS fargate cluster name |
ecs_service_name | ECS fargate service name |
ecs_container_name | ECS fargate container name |
Environment Variable Replacements
Certain placeholders are used to represent environment-specific values within environment variables. These placeholders will be replaced with the appropriate values during the deployment or runtime of the ECS Fargate tasks. Here is the list of placeholders:
Name | Description |
---|---|
ALB_URL | ALB HTTP URL (http://<alb_dns_name> ) |
DB_NAME | Database name |
DB_USERNAME | Database username |
DB_PASSWORD | Database password |
DB_CLUSTER_ENDPOINT | Aurora cluster load-balanced endpoint |
DB_MASTER_ENDPOINT | Aurora master instance endpoint |
DB_READER_ENDPOINT | Aurora cluster load-balanced reader endpoint |
DB_REPLICAS_ENDPOINT | Comma separated database replica endpoints |
DB_ENDPOINTS | Comma separated list of database instance endpoints |
TODO
The following items are areas of improvement and additional features that can be added to the module in the future:
- Update the ALB listener to use the SSL certificate and configure HTTPS connections.
- Implement auto-scaling for the ECS Fargate tasks to handle varying levels of traffic and ensure optimal resource utilization.
- Evaluate and implement additional performance optimizations for the ECS tasks, such as caching strategies and content delivery networks (CDN).
License
This module is released under the MIT License.
Authors
Roman Novák |
---|
Don't hesitate to open an issue or pull request if you find any issues or have suggestions for improvements. Your contributions are always welcome!