Skip to content

Commit f50a1cf

Browse files
committed
Initial release
1 parent e0be120 commit f50a1cf

File tree

9 files changed

+907
-1
lines changed

9 files changed

+907
-1
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 Giampaolo
3+
Copyright (c) 2024 Giampaolo Falqui
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Terraform AWS Directus Module
2+
3+
This Terraform module deploys Directus on an AWS Fargate ECS cluster.
4+
5+
## Features
6+
7+
- Easy deployment of Directus on AWS Fargate ECS
8+
- Automatic scaling and load balancing
9+
- Highly available and fault-tolerant architecture
10+
- Customizable configuration options
11+
- S3 integration for static assets
12+
13+
## To-Be-Done
14+
15+
- Implement Redis to allow multi-container deployment (currently only one is supported) (https://docs.directus.io/self-hosted/config-options.html#redis)
16+
- Implement Amazon Cognito authentication
17+
18+
## Prerequisites
19+
20+
Before using this module, make sure you have the following prerequisites:
21+
22+
- AWS account
23+
- Terraform installed
24+
- Basic knowledge of AWS services and Terraform
25+
26+
## Usage
27+
28+
To use this module, follow these steps:
29+
30+
1. Clone the repository:
31+
32+
```bash
33+
git clone https://github.com/your-username/terraform-aws-directus.git
34+
```
35+
36+
2. Change into the module directory:
37+
38+
```bash
39+
cd terraform-aws-directus/examples
40+
```
41+
42+
3. Initialize the Terraform workspace:
43+
44+
```bash
45+
terraform init
46+
```
47+
48+
4. Customize the module variables in `variables.tf` according to your requirements.
49+
50+
5. Deploy the Directus infrastructure:
51+
52+
```bash
53+
terraform apply
54+
```
55+
56+
6. Access the Directus application using the provided URL.
57+
58+
## Requirements
59+
60+
No requirements.
61+
62+
## Providers
63+
64+
| Name | Version |
65+
|------|---------|
66+
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |
67+
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
68+
69+
## Modules
70+
71+
| Name | Source | Version |
72+
|------|--------|---------|
73+
| <a name="module_ecs"></a> [ecs](#module\_ecs) | terraform-aws-modules/ecs/aws | 5.11.2 |
74+
75+
## Resources
76+
77+
| Name | Type |
78+
|------|------|
79+
| [aws_ecs_service.directus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service) | resource |
80+
| [aws_ecs_task_definition.directus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition) | resource |
81+
| [aws_iam_access_key.directus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_access_key) | resource |
82+
| [aws_iam_policy.cloudwatch-logs-policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
83+
| [aws_iam_role.ecs-service-role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
84+
| [aws_iam_role.ecs-task-role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
85+
| [aws_iam_role_policy_attachment.ecs-service-role-ecs-task-execution](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
86+
| [aws_iam_user.directus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user) | resource |
87+
| [aws_iam_user_policy.lb_ro](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_policy) | resource |
88+
| [aws_lb.directus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource |
89+
| [aws_lb_listener.directus-lb-listener-http](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource |
90+
| [aws_lb_target_group.directus-lb-target-group-http](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource |
91+
| [aws_s3_bucket.directus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
92+
| [aws_secretsmanager_secret.directus-admin-password](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
93+
| [aws_secretsmanager_secret.directus-secret](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
94+
| [aws_secretsmanager_secret.directus-serviceuser-secret](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
95+
| [aws_secretsmanager_secret_version.directus-admin-password-version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
96+
| [aws_secretsmanager_secret_version.directus-secret-version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
97+
| [aws_secretsmanager_secret_version.directus-serviceuser-secret-version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
98+
| [aws_security_group.ecs-sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
99+
| [aws_security_group.lb_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
100+
| [random_password.directus-admin-password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
101+
| [random_password.directus-secret](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
102+
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
103+
| [aws_iam_policy_document.cloudwatch-policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
104+
| [aws_iam_policy_document.s3-policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
105+
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
106+
| [aws_s3_bucket.directus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket) | data source |
107+
108+
## Inputs
109+
110+
| Name | Description | Type | Default | Required |
111+
|------|-------------|------|---------|:--------:|
112+
| <a name="input_additional_configuration"></a> [additional\_configuration](#input\_additional\_configuration) | Additional configuration to apply to the Directus container | `map(string)` | `{}` | no |
113+
| <a name="input_admin_email"></a> [admin\_email](#input\_admin\_email) | The email address of the admin user | `string` | n/a | yes |
114+
| <a name="input_admin_password"></a> [admin\_password](#input\_admin\_password) | The password of the admin user (if empty, it will be generated automatically) | `string` | `""` | no |
115+
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | The name of the application | `string` | n/a | yes |
116+
| <a name="input_cloudwatch_logs_stream_prefix"></a> [cloudwatch\_logs\_stream\_prefix](#input\_cloudwatch\_logs\_stream\_prefix) | The prefix of the CloudWatch Logs stream | `string` | `"directus"` | no |
117+
| <a name="input_cpu"></a> [cpu](#input\_cpu) | The number of CPU units to reserve for the Directus service | `number` | `2048` | no |
118+
| <a name="input_create_cloudwatch_logs_group"></a> [create\_cloudwatch\_logs\_group](#input\_create\_cloudwatch\_logs\_group) | Whether to create a CloudWatch Logs group | `bool` | `false` | no |
119+
| <a name="input_create_s3_bucket"></a> [create\_s3\_bucket](#input\_create\_s3\_bucket) | Whether to create an S3 bucket | `bool` | `false` | no |
120+
| <a name="input_healthcheck_path"></a> [healthcheck\_path](#input\_healthcheck\_path) | The path of the healthcheck endpoint | `string` | `"/server/ping"` | no |
121+
| <a name="input_image_tag"></a> [image\_tag](#input\_image\_tag) | The tag of the Docker image | `string` | `"latest"` | no |
122+
| <a name="input_memory"></a> [memory](#input\_memory) | The amount of memory to reserve for the Directus service | `number` | `4096` | no |
123+
| <a name="input_rds_database_engine"></a> [rds\_database\_engine](#input\_rds\_database\_engine) | The engine of the RDS database | `string` | n/a | yes |
124+
| <a name="input_rds_database_host"></a> [rds\_database\_host](#input\_rds\_database\_host) | The host of the RDS database | `string` | n/a | yes |
125+
| <a name="input_rds_database_name"></a> [rds\_database\_name](#input\_rds\_database\_name) | The Name of the RDS database | `string` | n/a | yes |
126+
| <a name="input_rds_database_password_secrets_manager_arn"></a> [rds\_database\_password\_secrets\_manager\_arn](#input\_rds\_database\_password\_secrets\_manager\_arn) | The ARN of the Secrets Manager secret containing the RDS database password | `string` | n/a | yes |
127+
| <a name="input_rds_database_port"></a> [rds\_database\_port](#input\_rds\_database\_port) | The port of the RDS database | `number` | n/a | yes |
128+
| <a name="input_rds_database_username"></a> [rds\_database\_username](#input\_rds\_database\_username) | The username of the RDS database user | `string` | n/a | yes |
129+
| <a name="input_s3_bucket_name"></a> [s3\_bucket\_name](#input\_s3\_bucket\_name) | The name of the S3 bucket | `string` | `""` | no |
130+
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | The IDs of the subnets | `list(string)` | n/a | yes |
131+
| <a name="input_tags"></a> [tags](#input\_tags) | The tags to apply to the resources | `map(string)` | `{}` | no |
132+
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | The ID of the VPC | `string` | n/a | yes |
133+
134+
## Outputs
135+
136+
| Name | Description |
137+
|------|-------------|
138+
| <a name="output_load_balancer_dns_name"></a> [load\_balancer\_dns\_name](#output\_load\_balancer\_dns\_name) | n/a |
139+
| <a name="output_s3_bucket_arn"></a> [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | n/a |
140+
| <a name="output_s3_bucket_name"></a> [s3\_bucket\_name](#output\_s3\_bucket\_name) | n/a |
141+
142+
143+
## Contributing
144+
145+
Contributions to this module are welcome! If you encounter any issues or have suggestions for improvements, please open an issue or submit a pull request on the GitHub repository.
146+
147+
## License
148+
149+
This module is open source and available under the [MIT License](https://opensource.org/licenses/MIT).

examples/.terraform.lock.hcl

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/main.tf

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
provider "aws" {
2+
region = local.region
3+
}
4+
5+
data "aws_availability_zones" "available" {}
6+
7+
locals {
8+
name = "terraform-aws-directus"
9+
10+
region = "eu-central-1"
11+
12+
vpc_cidr = "10.0.0.0/16"
13+
azs = slice(data.aws_availability_zones.available.names, 0, 3)
14+
15+
tags = {
16+
Name = local.name
17+
Example = local.name
18+
Repository = "https://github.com/GiamPy5/terraform-aws-directus"
19+
}
20+
}
21+
22+
################################################################################
23+
# RDS Module
24+
################################################################################
25+
26+
module "directus" {
27+
source = "./.."
28+
29+
application_name = local.name # Change this to your application name
30+
admin_email = "[email protected]" # Change this to your email address
31+
vpc_id = module.vpc.vpc_id # Change this to your VPC ID
32+
subnet_ids = module.vpc.public_subnets # Change this to your subnet IDs
33+
34+
create_cloudwatch_logs_group = true
35+
cloudwatch_logs_stream_prefix = "directus"
36+
37+
cpu = 2048
38+
memory = 4096
39+
40+
rds_database_name = module.rds.db_instance_name
41+
rds_database_host = module.rds.db_instance_address
42+
rds_database_port = module.rds.db_instance_port
43+
rds_database_engine = module.rds.db_instance_engine
44+
rds_database_username = module.rds.db_instance_username
45+
rds_database_password_secrets_manager_arn = module.rds.db_instance_master_user_secret_arn
46+
47+
create_s3_bucket = true # If you do not create an S3 bucket, you will need to provide an existing S3 bucket name
48+
s3_bucket_name = "terraform-aws-directus-${local.region}"
49+
50+
healthcheck_path = "/server/ping"
51+
image_tag = "latest" # It's HIGHLY RECOMMENDED to specify an image tag instead of relying on "latest" as it could trigger unwanted updates.
52+
53+
tags = {
54+
Application = "Directus"
55+
Environment = "Test"
56+
} # Change these tags to your prefered tags
57+
}
58+
59+
################################################################################
60+
# Supporting Resources
61+
################################################################################
62+
63+
module "vpc" {
64+
source = "terraform-aws-modules/vpc/aws"
65+
version = "~> 5.0"
66+
67+
name = local.name
68+
cidr = local.vpc_cidr
69+
70+
azs = local.azs
71+
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
72+
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
73+
database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)]
74+
75+
create_database_subnet_group = true
76+
77+
tags = local.tags
78+
}
79+
80+
module "security_group" {
81+
source = "terraform-aws-modules/security-group/aws"
82+
version = "~> 5.0"
83+
84+
name = local.name
85+
description = "Complete MySQL example security group"
86+
vpc_id = module.vpc.vpc_id
87+
88+
# ingress
89+
ingress_with_cidr_blocks = [
90+
{
91+
from_port = 3306
92+
to_port = 3306
93+
protocol = "tcp"
94+
description = "MySQL access from within VPC"
95+
cidr_blocks = module.vpc.vpc_cidr_block
96+
},
97+
]
98+
99+
tags = local.tags
100+
}
101+
102+
module "rds" {
103+
source = "terraform-aws-modules/rds/aws"
104+
version = "6.7.0"
105+
106+
identifier = "directus"
107+
108+
engine = "mysql"
109+
family = "mysql5.7"
110+
major_engine_version = "5.7"
111+
engine_version = "5.7"
112+
instance_class = "db.t3.micro"
113+
allocated_storage = 5
114+
115+
db_name = "directus"
116+
username = "user"
117+
port = "3306"
118+
119+
vpc_security_group_ids = [module.security_group.security_group_id]
120+
db_subnet_group_name = module.vpc.database_subnet_group
121+
122+
manage_master_user_password = true
123+
}

examples/outputs.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
output "s3_bucket_name" {
2+
value = module.directus.s3_bucket_name
3+
}
4+
5+
output "s3_bucket_arn" {
6+
value = module.directus.s3_bucket_arn
7+
}
8+
9+
output "load_balancer_dns_name" {
10+
value = module.directus.load_balancer_dns_name
11+
}

0 commit comments

Comments
 (0)