Skip to content

Commit 9e9bb51

Browse files
authored
feat: Adds Cognito integration (#12)
1 parent f893736 commit 9e9bb51

File tree

4 files changed

+111
-15
lines changed

4 files changed

+111
-15
lines changed

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,6 @@ Before using this module, ensure you have the following:
7979
- **Terraform installed** on your machine 🌐
8080
- Basic knowledge of **AWS services** and **Terraform** 📚
8181

82-
## 📅 Roadmap
83-
84-
- [ ] Implement Amazon Cognito authentication
85-
8682
## 📚 Module Documentation
8783

8884
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
@@ -136,9 +132,11 @@ Before using this module, ensure you have the following:
136132
| [aws_s3_bucket.directus](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
137133
| [aws_s3_bucket_server_side_encryption_configuration.example](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
138134
| [aws_s3_bucket_versioning.directus_bucket_versioning](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
135+
| [aws_secretsmanager_secret.cognito_client_secret](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
139136
| [aws_secretsmanager_secret.directus_admin_password](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
140137
| [aws_secretsmanager_secret.directus_secret](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
141138
| [aws_secretsmanager_secret.directus_serviceuser_secret](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret) | resource |
139+
| [aws_secretsmanager_secret_version.cognito_client_secret_version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
142140
| [aws_secretsmanager_secret_version.directus_admin_password_version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
143141
| [aws_secretsmanager_secret_version.directus_secret_version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
144142
| [aws_secretsmanager_secret_version.directus_serviceuser_secret_version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version) | resource |
@@ -147,6 +145,7 @@ Before using this module, ensure you have the following:
147145
| [random_password.directus_admin_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
148146
| [random_password.directus_secret](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) | resource |
149147
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
148+
| [aws_cognito_user_pool_client.client](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/cognito_user_pool_client) | data source |
150149
| [aws_iam_policy_document.cloudwatch_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
151150
| [aws_iam_policy_document.kms_access_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
152151
| [aws_iam_policy_document.kms_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
@@ -164,11 +163,17 @@ Before using this module, ensure you have the following:
164163
| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | The name of the application | `string` | n/a | yes |
165164
| <a name="input_autoscaling"></a> [autoscaling](#input\_autoscaling) | Autoscaling Configuration | <pre>object({<br> enable = bool<br> memory_threshold = number<br> cpu_threshold = number<br> min_capacity = number<br> max_capacity = number<br> })</pre> | <pre>{<br> "cpu_threshold": 60,<br> "enable": false,<br> "max_capacity": 3,<br> "memory_threshold": 80,<br> "min_capacity": 1<br>}</pre> | no |
166165
| <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 |
166+
| <a name="input_cognito_allow_public_registration"></a> [cognito\_allow\_public\_registration](#input\_cognito\_allow\_public\_registration) | Whether to allow public registration in Directus through Cognito External Users | `bool` | `false` | no |
167+
| <a name="input_cognito_identifier_key"></a> [cognito\_identifier\_key](#input\_cognito\_identifier\_key) | The key of the Cognito identifier | `string` | `"email"` | no |
168+
| <a name="input_cognito_scopes"></a> [cognito\_scopes](#input\_cognito\_scopes) | The Cognito scopes | `list(string)` | <pre>[<br> "email",<br> "openid",<br> "profile"<br>]</pre> | no |
169+
| <a name="input_cognito_user_pool_client_id"></a> [cognito\_user\_pool\_client\_id](#input\_cognito\_user\_pool\_client\_id) | The ID of the Cognito user pool client | `string` | `""` | no |
170+
| <a name="input_cognito_user_pool_id"></a> [cognito\_user\_pool\_id](#input\_cognito\_user\_pool\_id) | The ID of the Cognito user pool | `string` | `""` | no |
167171
| <a name="input_cpu"></a> [cpu](#input\_cpu) | The number of CPU units to reserve for the Directus service | `number` | `2048` | no |
168172
| <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 |
169173
| <a name="input_create_s3_bucket"></a> [create\_s3\_bucket](#input\_create\_s3\_bucket) | Whether to create an S3 bucket | `bool` | `false` | no |
170174
| <a name="input_ecs_service_enable_execute_command"></a> [ecs\_service\_enable\_execute\_command](#input\_ecs\_service\_enable\_execute\_command) | Whether to enable ECS service execute command | `bool` | `false` | no |
171175
| <a name="input_enable_alb_access_logs"></a> [enable\_alb\_access\_logs](#input\_enable\_alb\_access\_logs) | Whether to enable access logs of the Load Balancer | `bool` | `false` | no |
176+
| <a name="input_enable_cognito_authentication"></a> [enable\_cognito\_authentication](#input\_enable\_cognito\_authentication) | Whether to enable Cognito authentication | `bool` | `false` | no |
172177
| <a name="input_enable_ecs_volume"></a> [enable\_ecs\_volume](#input\_enable\_ecs\_volume) | Whether to enable ECS volume | `bool` | `false` | no |
173178
| <a name="input_enable_kms_encryption"></a> [enable\_kms\_encryption](#input\_enable\_kms\_encryption) | Whether to enable KMS encryption | `bool` | `false` | no |
174179
| <a name="input_enable_s3_bucket_versioning"></a> [enable\_s3\_bucket\_versioning](#input\_enable\_s3\_bucket\_versioning) | Whether to enable S3 bucket versioning | `bool` | `true` | no |

examples/main.tf

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ module "directus" {
4949
cpu = 1024
5050
memory = 2048
5151

52+
enable_cognito_authentication = true
53+
cognito_allow_public_registration = true
54+
cognito_user_pool_id = "user_pool_id"
55+
cognito_user_pool_client_id = "user_pool_client_id"
56+
5257
ecs_service_enable_execute_command = true # Allows you to connect via CLI to the ECS Task Container (just like `docker exec`). It's disabled by default.
5358
enable_ses_emails_sending = true
5459
enable_ecs_volume = false
@@ -72,7 +77,7 @@ module "directus" {
7277
redis_port = module.elasticache.cluster_cache_nodes[0].port
7378

7479
create_s3_bucket = true # If you do not create an S3 bucket, you will need to provide an existing S3 bucket name
75-
s3_bucket_name = "terraform-aws-directus-${local.region}"
80+
s3_bucket_name = "${local.name}-${local.region}"
7681

7782
enable_kms_encryption = true
7883
kms_key_id = aws_kms_key.directus.id
@@ -160,7 +165,7 @@ module "rds" {
160165
source = "terraform-aws-modules/rds/aws"
161166
version = "6.7.0"
162167

163-
identifier = "directus"
168+
identifier = local.name
164169

165170
engine = "mysql"
166171
family = "mysql8.0"
@@ -347,7 +352,7 @@ resource "aws_cloudfront_distribution" "cloudfront_distribution" {
347352
target_origin_id = "lb.${local.application_domain_name}"
348353
viewer_protocol_policy = "redirect-to-https"
349354
forwarded_values {
350-
headers = []
355+
headers = ["Authorization"]
351356
query_string = true
352357
cookies {
353358
forward = "all"

main.tf

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ locals {
1313

1414
s3_bucket_name = var.s3_bucket_name != "" ? var.s3_bucket_name : "${local.truncated_application_name}-${local.service_name}-bucket-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}"
1515

16+
cognito_issuer_url = var.enable_cognito_authentication ? "https://cognito-idp.${data.aws_region.current.name}.amazonaws.com/${var.cognito_user_pool_id}/.well-known/openid-configuration" : ""
17+
1618
directus_port = 8055
1719

20+
openid_callback_url = "${local.public_url}/auth/login/cognito/callback"
21+
1822
healthcheck_path = "/server/health"
1923

2024
public_url = var.public_url != "" ? var.public_url : "http://${aws_lb.directus.dns_name}"
@@ -54,6 +58,16 @@ locals {
5458
var.enable_ses_emails_sending ? {
5559
EMAIL_TRANSPORT = "ses"
5660
EMAIL_SES_REGION = data.aws_region.current.name
61+
} : {},
62+
var.enable_cognito_authentication ? {
63+
AUTH_PROVIDERS = "cognito"
64+
AUTH_COGNITO_DRIVER = "openid"
65+
AUTH_COGNITO_ISSUER_URL = local.cognito_issuer_url
66+
AUTH_COGNITO_SCOPE = join(" ", var.cognito_scopes)
67+
AUTH_COGNITO_CLIENT_ID = var.cognito_user_pool_client_id
68+
AUTH_COGNITO_IDENTIFIER_KEY = var.cognito_identifier_key
69+
AUTH_COGNITO_ALLOW_PUBLIC_REGISTRATION = var.cognito_allow_public_registration ? "true" : "false"
70+
AUTH_COGNITO_ICON = "aws"
5771
} : {}
5872
)
5973

@@ -64,16 +78,20 @@ locals {
6478
cpu = var.cpu
6579
memory = var.memory
6680
essential = true
67-
secrets = concat([
68-
{ name : "SECRET", valueFrom : aws_secretsmanager_secret_version.directus_secret_version.arn },
69-
{ name : "ADMIN_PASSWORD", valueFrom : aws_secretsmanager_secret_version.directus_admin_password_version.arn },
70-
{ name : "DB_PASSWORD", valueFrom : "${var.rds_database_password_secrets_manager_arn}:password::" },
71-
{ name : "STORAGE_S3_KEY", valueFrom : "${aws_secretsmanager_secret_version.directus_serviceuser_secret_version.arn}:access_key_id::" },
72-
{ name : "STORAGE_S3_SECRET", valueFrom : "${aws_secretsmanager_secret_version.directus_serviceuser_secret_version.arn}:access_key_secret::" }
81+
secrets = concat(
82+
[
83+
{ name : "SECRET", valueFrom : aws_secretsmanager_secret_version.directus_secret_version.arn },
84+
{ name : "ADMIN_PASSWORD", valueFrom : aws_secretsmanager_secret_version.directus_admin_password_version.arn },
85+
{ name : "DB_PASSWORD", valueFrom : "${var.rds_database_password_secrets_manager_arn}:password::" },
86+
{ name : "STORAGE_S3_KEY", valueFrom : "${aws_secretsmanager_secret_version.directus_serviceuser_secret_version.arn}:access_key_id::" },
87+
{ name : "STORAGE_S3_SECRET", valueFrom : "${aws_secretsmanager_secret_version.directus_serviceuser_secret_version.arn}:access_key_secret::" }
7388
],
7489
var.enable_ses_emails_sending ? [
7590
{ name : "EMAIL_SES_CREDENTIALS__ACCESS_KEY_ID", valueFrom : "${aws_secretsmanager_secret_version.directus_serviceuser_secret_version.arn}:access_key_id::" },
7691
{ name : "EMAIL_SES_CREDENTIALS__SECRET_ACCESS_KEY", valueFrom : "${aws_secretsmanager_secret_version.directus_serviceuser_secret_version.arn}:access_key_secret::" }
92+
] : [],
93+
var.enable_cognito_authentication ? [
94+
{ name : "AUTH_COGNITO_CLIENT_SECRET", valueFrom : aws_secretsmanager_secret_version.cognito_client_secret_version[0].arn }
7795
] : [])
7896
environment = [for key, value in local.environment_vars : {
7997
name = key
@@ -113,6 +131,37 @@ data "aws_region" "current" {}
113131

114132
data "aws_caller_identity" "current" {}
115133

134+
data "aws_cognito_user_pool_client" "client" {
135+
count = var.enable_cognito_authentication ? 1 : 0
136+
137+
client_id = var.cognito_user_pool_client_id
138+
user_pool_id = var.cognito_user_pool_id
139+
}
140+
141+
resource "aws_secretsmanager_secret" "cognito_client_secret" {
142+
count = var.enable_cognito_authentication ? 1 : 0
143+
144+
name_prefix = "${var.application_name}-${local.service_name}-cognito-client-secret"
145+
146+
kms_key_id = var.kms_key_id
147+
148+
tags = var.tags
149+
}
150+
151+
resource "aws_secretsmanager_secret_version" "cognito_client_secret_version" {
152+
count = var.enable_cognito_authentication ? 1 : 0
153+
154+
secret_id = aws_secretsmanager_secret.cognito_client_secret[0].id
155+
secret_string = data.aws_cognito_user_pool_client.client[0].client_secret
156+
157+
lifecycle {
158+
precondition {
159+
condition = contains(data.aws_cognito_user_pool_client.client[0].callback_urls, local.openid_callback_url)
160+
error_message = "The Cognito user pool client \"${var.cognito_user_pool_client_id}\" callback URLs must contain \"${local.openid_callback_url}\""
161+
}
162+
}
163+
}
164+
116165
resource "aws_s3_bucket" "directus" {
117166
count = var.create_s3_bucket ? 1 : 0
118167

@@ -236,12 +285,14 @@ module "ecs" {
236285
"kms" : aws_iam_policy.kms_policy[0].arn
237286
} : {})
238287

239-
task_exec_secret_arns = [
288+
task_exec_secret_arns = concat([
240289
aws_secretsmanager_secret.directus_secret.arn,
241290
aws_secretsmanager_secret.directus_admin_password.arn,
242291
aws_secretsmanager_secret.directus_serviceuser_secret.arn,
243292
var.rds_database_password_secrets_manager_arn
244-
]
293+
], var.enable_cognito_authentication ? [
294+
aws_secretsmanager_secret.cognito_client_secret[0].arn
295+
] : [])
245296

246297
cluster_configuration = {
247298
execute_command_configuration = {

variables.tf

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,41 @@ variable "public_url" {
1010
default = ""
1111
}
1212

13+
variable "enable_cognito_authentication" {
14+
description = "Whether to enable Cognito authentication"
15+
type = bool
16+
default = false
17+
}
18+
19+
variable "cognito_allow_public_registration" {
20+
description = "Whether to allow public registration in Directus through Cognito External Users"
21+
type = bool
22+
default = false
23+
}
24+
25+
variable "cognito_identifier_key" {
26+
description = "The key of the Cognito identifier"
27+
type = string
28+
default = "email"
29+
}
30+
31+
variable "cognito_scopes" {
32+
description = "The Cognito scopes"
33+
type = list(string)
34+
default = ["email", "openid", "profile"]
35+
}
36+
variable "cognito_user_pool_id" {
37+
description = "The ID of the Cognito user pool"
38+
type = string
39+
default = ""
40+
}
41+
42+
variable "cognito_user_pool_client_id" {
43+
description = "The ID of the Cognito user pool client"
44+
type = string
45+
default = ""
46+
}
47+
1348
variable "load_balancer_allowed_cidr_blocks" {
1449
description = "The CIDR blocks allowed to access the Load Balancer"
1550
type = list(string)

0 commit comments

Comments
 (0)