From 3284551ef44741498a455f71bd58da2063ff640a Mon Sep 17 00:00:00 2001 From: Josep Boix Requesens Date: Thu, 28 Nov 2024 15:56:27 +0100 Subject: [PATCH] feat: add bastion configuration to terraform Added a terraform configuration to allow the creation of a bastion host for remote access and management of the OpenSearch cluster. --- README.md | 4 + pillarbox-event-dispatcher | 2 +- .../20-pillarbox-monitoring-app/iam.tf | 2 +- .../20-pillarbox-monitoring-app/locals.tf | 2 +- .../20-pillarbox-monitoring-app/main.tf | 2 +- .../20-pillarbox-monitoring-app/opensearch.tf | 2 +- .../22-bastion/.terraform.lock.hcl | 25 ++++ .../22-bastion/locals.tf | 13 ++ .../22-bastion/main.tf | 128 ++++++++++++++++++ .../22-bastion/variables.tf | 21 +++ pillarbox-monitoring-transfer | 2 +- 11 files changed, 197 insertions(+), 6 deletions(-) create mode 100644 pillarbox-monitoring-terraform/22-bastion/.terraform.lock.hcl create mode 100644 pillarbox-monitoring-terraform/22-bastion/locals.tf create mode 100644 pillarbox-monitoring-terraform/22-bastion/main.tf create mode 100644 pillarbox-monitoring-terraform/22-bastion/variables.tf diff --git a/README.md b/README.md index 08c7c00..df37a2d 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,10 @@ The project is split into four main Terraform configurations: allow access to GitHub Action for specific repositories and operations. **This applies to both dev and prod environments**. You can switch between workspaces (as mentioned earlier) to deploy infrastructure in either the dev or prod account. +- [22-bastion][app]: Configures a bastion host for secure remote access and management of the + OpenSearch cluster. **This applies to both dev and prod environments**. You can switch + between workspaces (as mentioned earlier) to deploy infrastructure in either the dev or prod + account. ### System Flow Overview diff --git a/pillarbox-event-dispatcher b/pillarbox-event-dispatcher index 12bafbd..7a34038 160000 --- a/pillarbox-event-dispatcher +++ b/pillarbox-event-dispatcher @@ -1 +1 @@ -Subproject commit 12bafbd8f2285c0ca314fea6fd131e5a8ab56014 +Subproject commit 7a34038102d50adc379cc78d64c5b499720caecd diff --git a/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/iam.tf b/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/iam.tf index f886dcc..8ffc364 100644 --- a/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/iam.tf +++ b/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/iam.tf @@ -167,7 +167,7 @@ data "aws_iam_policy_document" "opensearch_policy" { actions = ["es:*"] resources = [ - "arn:aws:es:${data.aws_region.current.name}:${local.accout_id}:domain/${local.opensearch.domain_name}/*" + "arn:aws:es:${data.aws_region.current.name}:${local.account_id}:domain/${local.opensearch.domain_name}/*" ] } } diff --git a/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/locals.tf b/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/locals.tf index 2ac09d5..3580c03 100644 --- a/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/locals.tf +++ b/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/locals.tf @@ -1,5 +1,5 @@ locals { - accout_id = var.account_ids[terraform.workspace] + account_id = var.account_ids[terraform.workspace] vpc_id = var.vpc_ids[terraform.workspace] ecs_cluster_name = "${var.application_name}-cluster" is_prod = terraform.workspace == "prod" diff --git a/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/main.tf b/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/main.tf index 1535dde..90e9d6b 100644 --- a/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/main.tf +++ b/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/main.tf @@ -26,7 +26,7 @@ terraform { # ----------------------------------- provider "aws" { - allowed_account_ids = [local.accout_id] + allowed_account_ids = [local.account_id] # Apply default tags to all AWS resources default_tags { diff --git a/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/opensearch.tf b/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/opensearch.tf index 643abb5..fa1e963 100644 --- a/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/opensearch.tf +++ b/pillarbox-monitoring-terraform/20-pillarbox-monitoring-app/opensearch.tf @@ -4,7 +4,7 @@ resource "aws_opensearch_domain" "opensearch_domain" { domain_name = local.opensearch.domain_name - engine_version = "OpenSearch_2.15" + engine_version = "OpenSearch_2.17" # Cluster configuration including instance type and count cluster_config { diff --git a/pillarbox-monitoring-terraform/22-bastion/.terraform.lock.hcl b/pillarbox-monitoring-terraform/22-bastion/.terraform.lock.hcl new file mode 100644 index 0000000..6a1d7aa --- /dev/null +++ b/pillarbox-monitoring-terraform/22-bastion/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.4.0" + constraints = "~> 5.4.0" + hashes = [ + "h1:V2yz+EYWnLU/fWdsk8UX7oFuAKTBLTHDdLKB6NG7th0=", + "zh:1db5f81089216831bb0fdff9ddc3772efa133397c66ec276bc75b96eec06e23f", + "zh:26fe5fdf399192b5724d21854fbec650c158f8ee9eb1dc52a50f7da0f2bc07ac", + "zh:2946d9e333b1efe01588ee9f9771169fd3c3a4a7cb78ed8f91e8b3efd1a73850", + "zh:36ed69e8d3029332c8a52a70940f714fd579b9fd95f5569cc010ef11162f5bf7", + "zh:46ba5ad1c3a3ef98c346356cfa4bdd9c2501c661c2513bb92f4413f2482fb24b", + "zh:46c10aaa9672b54a14b0e0effdd6ecd9b8a539b3bfe273ac54111e7352a7bb4b", + "zh:47d7f57bcbe4fba2f960ab6c4228c5e9e586be2f233a8baa8962b51a63337179", + "zh:47e41c198439ba1c4d933f808b6f47e518f8f0aae25ca42abcac97f149121e90", + "zh:526c5834de71654ee14039cb973322bf5032cb684a2a113b48fb48a0584f46f3", + "zh:6169316517b95677819ba2904dcea204fb9b55e868348e906af9164104fe7198", + "zh:7c063ef2b8d69a8db7e8bf0dcd45793ede22b259b30464ed114d330df304cdbb", + "zh:87c4f2faca636715a08be3121d26b3354415401eab89349077ca9436a0822c23", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:b184b8a268f45258edd27d389ca793708f1bc3ee4d6706d154a45e93deaddde1", + "zh:ba1a998cbf4b639fa3e04b9069f0f5a289662457940726a8a51c81df400aa852", + ] +} diff --git a/pillarbox-monitoring-terraform/22-bastion/locals.tf b/pillarbox-monitoring-terraform/22-bastion/locals.tf new file mode 100644 index 0000000..dc84da5 --- /dev/null +++ b/pillarbox-monitoring-terraform/22-bastion/locals.tf @@ -0,0 +1,13 @@ +locals { + bastion_ami = "ami-0d7c381edfc5ee30e" + bastion_instance_type = "t4g.nano" + vpc_id = var.vpc_ids[terraform.workspace] + + default_tags = { + "srg-managed-by" = "terraform" + "srg-application" = var.application_name + "srg-owner" = "pillarbox-team@rts.ch" + "srg-businessowner" = "pillarbox" + "srg-environment" = terraform.workspace + } +} diff --git a/pillarbox-monitoring-terraform/22-bastion/main.tf b/pillarbox-monitoring-terraform/22-bastion/main.tf new file mode 100644 index 0000000..0620eb1 --- /dev/null +++ b/pillarbox-monitoring-terraform/22-bastion/main.tf @@ -0,0 +1,128 @@ +# ----------------------------------- +# Terraform Configuration +# ----------------------------------- + +terraform { + # Backend configuration for storing the Terraform state in S3 with DynamoDB table for state locking + backend "s3" { + encrypt = true + bucket = "pillarbox-monitoring-tfstate" + key = "terraform/22-bastion/terraform.tfstate" + dynamodb_table = "pillarbox-monitoring-terraform-statelock" + profile = "prod" + } + + # Specify required providers and their versions + required_providers { + aws = { + source = "hashicorp/aws" + version = "~>5.4.0" + } + } +} + +# ----------------------------------- +# AWS Provider Setup +# ----------------------------------- + +provider "aws" { + # Apply default tags to all AWS resources + default_tags { + tags = local.default_tags + } +} + +# ----------------------------------- +# AWS Data Sources +# ----------------------------------- + +# Retrieve the VPC information +data "aws_vpc" "main_vpc" { + id = local.vpc_id +} + +# Retrieve public subnets based on VPC and tags +data "aws_subnets" "public_subnets" { + filter { + name = "vpc-id" + values = [data.aws_vpc.main_vpc.id] + } + + tags = { + Name = "*public*" + } +} + +# ----------------------------------- +# Bastion configuration +# ----------------------------------- + +resource "aws_key_pair" "bastion_key" { + key_name = "bastion-keypair" + public_key = var.bastion_public_key +} + +# Security Group for the Bastion Host +resource "aws_security_group" "bastion_sg" { + name = "bastion-sg" + description = "Allow SSH access by IP" + vpc_id = data.aws_vpc.main_vpc.id + + ingress { + description = "SSH from my IP" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = var.allowed_ips + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = var.allowed_ips + } +} + +# Bastion Host EC2 Instance in Public Subnet +resource "aws_instance" "bastion" { + ami = local.bastion_ami + instance_type = local.bastion_instance_type + subnet_id = data.aws_subnets.public_subnets.ids[0] + key_name = "bastion-keypair" + vpc_security_group_ids = [aws_security_group.bastion_sg.id] + associate_public_ip_address = true + + tags = { + Name = "bastion-host" + } +} + +# ----------------------------------- +# OpenSearch security group rule +# ----------------------------------- + +data "aws_security_group" "opensearch_sg" { + filter { + name = "group-name" + values = ["opensearch-sg"] + } +} + +resource "aws_security_group_rule" "new_ingress" { + type = "ingress" + from_port = 443 + to_port = 443 + protocol = "tcp" + source_security_group_id = aws_security_group.bastion_sg.id + security_group_id = data.aws_security_group.opensearch_sg.id +} + +# ----------------------------------- +# Outputs +# ----------------------------------- + +output "bastion_public_ip" { + description = "Public IP of the Bastion Host" + value = aws_instance.bastion.public_ip +} diff --git a/pillarbox-monitoring-terraform/22-bastion/variables.tf b/pillarbox-monitoring-terraform/22-bastion/variables.tf new file mode 100644 index 0000000..decda97 --- /dev/null +++ b/pillarbox-monitoring-terraform/22-bastion/variables.tf @@ -0,0 +1,21 @@ +variable "application_name" { + description = "The name of the application" + type = string + default = "pillarbox-monitoring" +} + +variable "vpc_ids" { + description = "VPC id map by terraform workspace" + type = map(string) +} + +# Variable for Public Key +variable "bastion_public_key" { + description = "Public key for the bastion host" + type = string +} + +variable "allowed_ips" { + description = "The list of ips that are allowed to connect to the bastion" + type = list(string) +} diff --git a/pillarbox-monitoring-transfer b/pillarbox-monitoring-transfer index c15357a..b67f462 160000 --- a/pillarbox-monitoring-transfer +++ b/pillarbox-monitoring-transfer @@ -1 +1 @@ -Subproject commit c15357acdf88e6779690e04bb9d14e0ab03532e5 +Subproject commit b67f462a9177efe911ad8426d9e834484d8a20ad