Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ yarn-error.log
# Deployement archives & builds
*.zip
bootstrap
lambda_payload.json
**lambda_response.json
143 changes: 127 additions & 16 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,56 @@ module "data" {
depends_on = [module.network]
}

module "rds_provisioner" {
source = "./modules/lambdas/iroco2-rds-db-provisioner"

lambda_function_name = "${var.namespace}-${var.environment}-rds-db-provisioner"
lambda_subnet_ids = module.network.private_subnet_ids
lambda_security_group_id = module.network.security_group_ids["iroco2-${var.environment}-rds-lambda-provisioner"]

lambda_force_invoke = false

rds_db_driver = "postgres"
rds_default_db_name = "irocalc"
rds_endpoint = module.data.rds_database.db_instance_address
rds_db_port = 5432
rds_db_user = "iroco2"

rds_secret_arn = module.data.rds_database_secret_arn

databases = [
"keycloak"
]
schemas = [
{ name = "keycloak", database = "keycloak", owner = "keycloak_readwrite" }
]
roles = [
{ name = "keycloak_readwrite" }
]
users = [
{ name = "keycloak", password_arn = module.data.rds_keycloak_secret_arn, roles = ["keycloak_readwrite"] }
]

grants = [
{
object_type = "DATABASE",
target = "keycloak",
grant_to = "keycloak",
database = "keycloak",
privileges = ["CONNECT"]
},
{
object_type = "SCHEMA",
target = "keycloak",
grant_to = "keycloak_readwrite",
database = "keycloak",
privileges = ["USAGE", "CREATE"]
}
]

depends_on = [module.data]
}

module "lambda_cur" {
source = "./modules/lambdas/iroco2-cur-analyzer"

Expand All @@ -80,15 +130,16 @@ module "backend_api" {
cur_s3_bucket_arn = module.lambda_cur.s3_cur_bucket_arn

# Network variables
vpc_id = module.network.vpc_id
private_subnet_ids = module.network.private_subnet_ids
alb_dns_name = module.network.alb_dns_name
alb_zone_id = module.network.alb_zone_id
alb_arn_suffix = module.network.alb_arn_suffix
alb_listener_arn = module.network.alb_listener_https_arn
alb_security_group_id = module.network.security_group_ids["iroco2-${var.environment}-alb"]
subdomain_name = var.subdomain_name
zone_name = var.zone_name
vpc_id = module.network.vpc_id
private_subnet_ids = module.network.private_subnet_ids
alb_dns_name = module.network.alb_dns_name
alb_zone_id = module.network.alb_zone_id
alb_arn_suffix = module.network.alb_arn_suffix
alb_listener_arn = module.network.alb_listener_https_arn
alb_health_check = "/actuator/health"
subdomain_name = var.subdomain_name
zone_name = var.zone_name
dns_prefix = "api"

# ECS variables
cluster_name = module.services.cluster.name
Expand All @@ -103,7 +154,8 @@ module "backend_api" {

task_container_environment = {
DATABASE_NAME = module.data.rds_database.db_instance_name
IROCO2_CORS_ALLOWED_ORIGINS = var.cors_allowed_origins
IROCO2_DATA_SOURCE_URL = module.data.rds_database.db_instance_endpoint
IROCO2_CORS_ALLOWED_ORIGINS = "https://${var.subdomain_name}.${var.zone_name},http://localhost:3000"
IROCO2_AWS_ANALYZER_SQS_QUEUE_NAME = module.lambda_cur.analyzer_sqs_cur_name
IROCO2_AWS_SCANNER_SQS_QUEUE_NAME = module.lambda_cur.scanner_sqs_cur_name
IROCO2_AWS_SQS_QUEUE_ENDPOINT = trimsuffix(module.lambda_cur.analyzer_sqs_cur_url, module.lambda_cur.analyzer_sqs_cur_name)
Expand All @@ -114,15 +166,11 @@ module "backend_api" {
IROCO2_CLERK_PUBLIC_KEY = module.services.ssm_parameters["clerk_public_key"].value
IROCO2_KMS_IDENTITY_KEY_ID = module.data.iroco_identity_provider_key_id.id
IROCO2_KMS_IDENTITY_PUBLIC_KEY = data.aws_kms_public_key.by_id.public_key
JWT_ISSUER = var.zone_name
JWT_AUDIENCE = var.zone_name
JWT_ISSUER = module.services.ssm_parameters["clerk_issuer"].value
JWT_AUDIENCE = module.services.ssm_parameters["clerk_audience"].value
}
task_container_secrets_arn = {}
task_container_secrets_arn_with_key = {
IROCO2_DATA_SOURCE_URL = {
arn = module.data.rds_database_secret_arn
key = "host"
}
IROCO2_DATA_SOURCE_USERNAME = {
arn = module.data.rds_database_secret_arn
key = "username"
Expand All @@ -141,3 +189,66 @@ module "backend_api" {
}
}
}

module "keycloak" {
source = "./modules/fargate-task"

# Global variables
aws_region = var.aws_region
project_name = "keycloak"
environment = var.environment

# Network variables
vpc_id = module.network.vpc_id
private_subnet_ids = module.network.private_subnet_ids
alb_dns_name = module.network.alb_dns_name
alb_zone_id = module.network.alb_zone_id
alb_arn_suffix = module.network.alb_arn_suffix
alb_listener_arn = module.network.alb_listener_https_arn
alb_health_check = "/health"
subdomain_name = var.subdomain_name
zone_name = var.zone_name
dns_prefix = "auth"

# ECS variables
cluster_name = module.services.cluster.name
cluster_id = module.services.cluster.id
container_cpu = 512
container_memory = 2048
container_port = 8080
container_image = "quay.io/keycloak/keycloak:24.0.1"
container_desired_count = var.container_desired_count
entrypoint = ["sh"]
container_command = ["-c", "/opt/keycloak/bin/kc.sh build --health-enabled=true && /opt/keycloak/bin/kc.sh start --http-enabled=true --hostname=$HOSTNAME"]
kms_identity_key_arn = data.aws_kms_key.signing_key.arn
ecs_backend_security_group_id = module.network.security_group_ids["iroco2-${var.environment}-keycloak"]

task_container_environment = {
HOSTNAME = "auth.${var.subdomain_name}.${var.zone_name}"
KC_PROXY = "edge"
KC_DB_URL = "jdbc:postgresql://${module.data.rds_database.db_instance_address}:5432/keycloak"
KC_DB = "postgres"
KC_DB_SCHEMA = "keycloak"
KC_HEALTH_ENABLED = "true"
KC_HEALTH_DB = "enabled"
}
task_container_secrets_arn = {}
task_container_secrets_arn_with_key = {
KEYCLOAK_ADMIN = {
arn = module.data.rds_keycloak_admin_secret_arn
key = "KEYCLOAK_ADMIN"
}
KEYCLOAK_ADMIN_PASSWORD = {
arn = module.data.rds_keycloak_admin_secret_arn
key = "KEYCLOAK_ADMIN_PASSWORD"
}
KC_DB_USERNAME = {
arn = module.data.rds_keycloak_secret_arn
key = "username"
}
KC_DB_PASSWORD = {
arn = module.data.rds_keycloak_secret_arn
key = "password"
}
}
}
11 changes: 11 additions & 0 deletions modules/data/00-outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ output "rds_database" {
value = {
db_instance_arn = module.rds.db_instance_arn
db_instance_endpoint = module.rds.db_instance_endpoint
db_instance_address = module.rds.db_instance_address
db_instance_name = module.rds.db_instance_name
db_instance_port = module.rds.db_instance_port
}
Expand All @@ -33,3 +34,13 @@ output "rds_database_secret_arn" {
value = aws_secretsmanager_secret.rds_master_pass.arn
description = "The ARN of the secret containing the RDS master password"
}

output "rds_keycloak_secret_arn" {
value = aws_secretsmanager_secret.rds_keycloak_pass.arn
description = "The ARN of the secret containing the RDS master password"
}

output "rds_keycloak_admin_secret_arn" {
value = aws_secretsmanager_secret.rds_keycloak_admin_pass.arn
description = "The ARN of the secret containing the RDS master password"
}
87 changes: 69 additions & 18 deletions modules/data/10-rds-password.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,90 @@
# SPDX-License-Identifier: Apache-2.0

# Initial password
resource "random_password" "rds_master_pass" {
ephemeral "random_password" "rds_master_pass" {
length = 40
special = false
}

# The secret
resource "aws_secretsmanager_secret" "rds_master_pass" {
name = "${var.namespace}/${var.environment}/rds/master-password-irocalc-db-secret"

tags = {
project = var.project_name
}
}

# Initial version
resource "aws_secretsmanager_secret_version" "rds_master_pass" {
secret_id = aws_secretsmanager_secret.rds_master_pass.id
secret_string_wo_version = 1
secret_string_wo = jsonencode(
{
username = var.namespace
password = ephemeral.random_password.rds_master_pass.result
}
)
}

ephemeral "aws_secretsmanager_secret_version" "rds_master_pass" {
secret_id = aws_secretsmanager_secret_version.rds_master_pass.secret_id
}

# Password for Keycloak DB
ephemeral "random_password" "rds_keycloak_pass" {
length = 40
special = true
min_special = 5
override_special = "!#$%^&*()-_=+[]{}<>:?"
}

# The secret for Keycloak DB
resource "aws_secretsmanager_secret" "rds_keycloak_pass" {
name = "${var.namespace}/${var.environment}/rds/keycloak-db-secret"

lifecycle {
ignore_changes = [
override_special,
min_special
]
tags = {
project = var.project_name
}
}

# The secret
resource "aws_secretsmanager_secret" "rds_master_pass" {
name = "${var.namespace}/${var.environment}/rds/master-password-irocalc-db-secret"
# Initial version for Keycloak DB
resource "aws_secretsmanager_secret_version" "rds_keycloak_pass" {
secret_id = aws_secretsmanager_secret.rds_keycloak_pass.id
secret_string_wo_version = 1
secret_string_wo = jsonencode(
{
username = "keycloak"
password = ephemeral.random_password.rds_keycloak_pass.result
}
)
}

# Password for Keycloak Admin
ephemeral "random_password" "rds_keycloak_admin_pass" {
length = 40
special = true
min_special = 5
override_special = "!#$%^&*()-_=+[]{}<>:?"
}

# The secret for Keycloak Admin
resource "aws_secretsmanager_secret" "rds_keycloak_admin_pass" {
name = "${var.namespace}/${var.environment}/rds/keycloak-admin-secret"

tags = {
project = var.project_name
}
}

# Initial version
resource "aws_secretsmanager_secret_version" "rds_master_pass" {
secret_id = aws_secretsmanager_secret.rds_master_pass.id
secret_string = jsonencode(
# Initial version for Keycloak Admin
resource "aws_secretsmanager_secret_version" "rds_keycloak_admin_pass" {
secret_id = aws_secretsmanager_secret.rds_keycloak_admin_pass.id
secret_string_wo_version = 1
secret_string_wo = jsonencode(
{
username = module.rds.db_instance_username
password = module.rds.db_instance_password
engine = module.rds.db_instance_engine
host = module.rds.db_instance_endpoint
jdbc_url = format("jdbc:postgresql://%s/%s", module.rds.db_instance_endpoint, var.rds_database_name)
KEYCLOAK_ADMIN = "keycloak-admin"
KEYCLOAK_ADMIN_PASSWORD = ephemeral.random_password.rds_keycloak_admin_pass.result
}
)
}
7 changes: 4 additions & 3 deletions modules/data/10-rds.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ locals {

module "rds" {
source = "terraform-aws-modules/rds/aws"
version = "5.2.3"
version = "7.0.1"

# General
identifier = local.rds_db_identifier
Expand All @@ -40,9 +40,10 @@ module "rds" {

# Security
username = var.namespace
password = random_password.rds_master_pass.result
password_wo = jsondecode(ephemeral.aws_secretsmanager_secret_version.rds_master_pass.secret_string).password
password_wo_version = aws_secretsmanager_secret_version.rds_master_pass.secret_string_wo_version
iam_database_authentication_enabled = false
create_random_password = false
manage_master_user_password = false

# Network
port = var.rds_database_port
Expand Down
2 changes: 1 addition & 1 deletion modules/data/20-bastion-ami.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ data "aws_ami" "amazon_linux_3" {
# name = "${var.namespace}-${var.environment}-bastion-${data.aws_ami.amazon_linux_3.name}-encrypted-temp"
# description = "A copy of ${data.aws_ami.amazon_linux_3.description} but encrypted"
# source_ami_id = data.aws_ami.amazon_linux_3.id
# source_ami_region = data.aws_region.current.name
# source_ami_region = data.aws_region.current.region
# encrypted = true
# tags = {
# image-type = "encrypted-al3-linux"
Expand Down
Loading
Loading