diff --git a/live/core-networking/bastion.tf b/live/core-networking/bastion.tf index 047154f..79a8551 100644 --- a/live/core-networking/bastion.tf +++ b/live/core-networking/bastion.tf @@ -7,14 +7,12 @@ variable "enable_bastion" { module "bastion" { count = var.enable_bastion ? 1 : 0 - source = "../../modules/bastion" - name = "${module.label.id}-bastion" - vpc_id = module.vpc.vpc_id - subnets = module.vpc.public_subnets - instance_type = "t2.micro" - associate_public_ip_address = true - associate_elastic_ip_address = false - tags = module.label.tags + source = "../../modules/bastion" + name = "${module.label.id}-bastion" + vpc_id = module.vpc.vpc_id + private_subnets = module.vpc.private_subnets + instance_type = "t2.micro" + tags = module.label.tags } output "bastion_instance_id" { diff --git a/modules/bastion/ami.tf b/modules/bastion/ami.tf index c1b133b..c269fdf 100644 --- a/modules/bastion/ami.tf +++ b/modules/bastion/ami.tf @@ -3,13 +3,6 @@ data "aws_ami" "ubuntu" { filter { name = "name" - values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] + values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"] } - - filter { - name = "virtualization-type" - values = ["hvm"] - } - - owners = ["099720109477"] # Canonical } diff --git a/modules/bastion/docs/MODULE.md b/modules/bastion/docs/MODULE.md index 721f9de..2a24ee5 100644 --- a/modules/bastion/docs/MODULE.md +++ b/modules/bastion/docs/MODULE.md @@ -1,4 +1,3 @@ - ## Requirements | Name | Version | @@ -19,12 +18,15 @@ |------|--------|---------| | [bastion](#module\_bastion) | terraform-aws-modules/ec2-instance/aws | ~> 3.0 | | [ec2\_security\_group](#module\_ec2\_security\_group) | terraform-aws-modules/security-group/aws | 4.17.1 | +| [ec2messages\_vpce\_sg](#module\_ec2messages\_vpce\_sg) | terraform-aws-modules/security-group/aws | 4.17.1 | +| [ssm\_vpce\_sg](#module\_ssm\_vpce\_sg) | terraform-aws-modules/security-group/aws | 4.17.1 | +| [ssmmessages\_vpce\_sg](#module\_ssmmessages\_vpce\_sg) | terraform-aws-modules/security-group/aws | 4.17.1 | +| [vpc\_endpoints](#module\_vpc\_endpoints) | ../../modules/vpc-endpoints | n/a | ## Resources | Name | Type | |------|------| -| [aws_eip.eip](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource | | [aws_iam_instance_profile.bastion_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | | [aws_iam_policy.ec2_instance_connect_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_role.bastion_host_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | @@ -40,15 +42,12 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [allowed\_cidrs](#input\_allowed\_cidrs) | Allow these CIDR blocks to the server - default is the Universe | `string` | `"0.0.0.0/0"` | no | +| [allowed\_cidrs](#input\_allowed\_cidrs) | Allow these CIDR blocks to instance | `string` | `null` | no | | [ami](#input\_ami) | AMI to use for the instance - will default to latest Ubuntu | `string` | `""` | no | -| [associate\_elastic\_ip\_address](#input\_associate\_elastic\_ip\_address) | Use an EIP for the instance | `bool` | `false` | no | -| [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | By default, our server has a public IP | `bool` | `true` | no | -| [enable\_ssh\_connection](#input\_enable\_ssh\_connection) | Enable SSH connection to the server | `bool` | `false` | no | | [instance\_type](#input\_instance\_type) | EC2 instance type/size - the default is not part of free tier! | `string` | `"t2.medium"` | no | | [key\_name](#input\_key\_name) | SSH key name to use for the instance | `string` | `""` | no | | [name](#input\_name) | Name to be used on all the resources as identifier | `string` | `""` | no | -| [subnets](#input\_subnets) | List of private subnets in which the EC2 instance is to be created. | `list(string)` | n/a | yes | +| [private\_subnets](#input\_private\_subnets) | List of private subnets in which the EC2 instance is to be created. | `list(string)` | n/a | yes | | [tags](#input\_tags) | Any extra tags to assign to objects | `map(any)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | VPC id in which the EC2 instance is to be created. | `string` | n/a | yes | @@ -59,4 +58,3 @@ | [instance\_id](#output\_instance\_id) | n/a | | [instance\_profile](#output\_instance\_profile) | n/a | | [ssm\_parameter\_ssh\_key](#output\_ssm\_parameter\_ssh\_key) | n/a | - \ No newline at end of file diff --git a/modules/bastion/ec2.tf b/modules/bastion/ec2.tf index 12d954c..3f738fb 100644 --- a/modules/bastion/ec2.tf +++ b/modules/bastion/ec2.tf @@ -1,7 +1,7 @@ locals { - _ssh_key_name = var.enable_ssh_connection ? ( + _ssh_key_name = ( length(var.key_name) > 0 ? var.key_name : aws_key_pair.ec2_ssh[0].key_name - ) : null + ) } // Script to configure the server - this is where most of the magic occurs! @@ -24,9 +24,8 @@ module "bastion" { user_data = data.template_file.user_data.rendered # network - subnet_id = element(var.subnets, 0) - vpc_security_group_ids = [module.ec2_security_group.security_group_id] - associate_public_ip_address = var.associate_public_ip_address + subnet_id = element(var.private_subnets, 0) + vpc_security_group_ids = [module.ec2_security_group.security_group_id] tags = var.tags } diff --git a/modules/bastion/eip.tf b/modules/bastion/eip.tf deleted file mode 100644 index 0b38c72..0000000 --- a/modules/bastion/eip.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "aws_eip" "eip" { - count = var.associate_elastic_ip_address ? 1 : 0 - - instance = module.bastion.id - domain = "vpc" - - tags = var.tags -} diff --git a/modules/bastion/sg.tf b/modules/bastion/sg.tf index 7568f91..48f39f4 100644 --- a/modules/bastion/sg.tf +++ b/modules/bastion/sg.tf @@ -3,12 +3,67 @@ module "ec2_security_group" { version = "4.17.1" name = "${var.name}-ec2" - description = "Allow SSH" + description = "Allow traffic on all ports and ip ranges" vpc_id = var.vpc_id - ingress_cidr_blocks = [var.allowed_cidrs] - ingress_rules = ["ssh-tcp"] - egress_rules = ["all-all"] + egress_rules = ["all-all"] + + tags = var.tags +} + +module "ssm_vpce_sg" { + source = "terraform-aws-modules/security-group/aws" + version = "4.17.1" + + name = "vpc-ssm-vpce-security-group" + description = "Security group for SSM VPC endpoint" + vpc_id = var.vpc_id + + ingress_with_source_security_group_id = [ + { + rule = "https-443-tcp" + source_security_group_id = module.ec2_security_group.security_group_id + description = "vpc ssm vpce security group ingress rule for bastion host" + } + ] + + tags = var.tags +} + +module "ec2messages_vpce_sg" { + source = "terraform-aws-modules/security-group/aws" + version = "4.17.1" + + name = "vpc-ec2messages-vpce-security-group" + description = "Security group for EC2 Messages VPC endpoint" + vpc_id = var.vpc_id + + ingress_with_source_security_group_id = [ + { + rule = "https-443-tcp" + source_security_group_id = module.ec2_security_group.security_group_id + description = "vpc ec2 messages vpce security group ingress rule for bastion host" + } + ] + + tags = var.tags +} + +module "ssmmessages_vpce_sg" { + source = "terraform-aws-modules/security-group/aws" + version = "4.17.1" + + name = "vpc-ssmmessages-vpce-security-group" + description = "Security group for SSM Messages VPC endpoint" + vpc_id = var.vpc_id + + ingress_with_source_security_group_id = [ + { + rule = "https-443-tcp" + source_security_group_id = module.ec2_security_group.security_group_id + description = "vpc ssm messages vpce security group ingress rule for bastion host" + } + ] tags = var.tags } diff --git a/modules/bastion/ssh-key.tf b/modules/bastion/ssh-key.tf index 41b4a3e..28515ec 100644 --- a/modules/bastion/ssh-key.tf +++ b/modules/bastion/ssh-key.tf @@ -1,5 +1,5 @@ locals { - disable_key_creation = !var.enable_ssh_connection || length(var.key_name) > 0 + disable_key_creation = length(var.key_name) > 0 } // Create EC2 ssh key pair diff --git a/modules/bastion/variables.tf b/modules/bastion/variables.tf index d815f19..90c484b 100644 --- a/modules/bastion/variables.tf +++ b/modules/bastion/variables.tf @@ -3,23 +3,11 @@ variable "vpc_id" { type = string } -variable "subnets" { +variable "private_subnets" { description = "List of private subnets in which the EC2 instance is to be created." type = list(string) } -variable "associate_public_ip_address" { - description = "By default, our server has a public IP" - type = bool - default = true -} - -variable "associate_elastic_ip_address" { - description = "Use an EIP for the instance" - type = bool - default = false -} - variable "ami" { description = "AMI to use for the instance - will default to latest Ubuntu" type = string @@ -34,15 +22,9 @@ variable "instance_type" { } variable "allowed_cidrs" { - description = "Allow these CIDR blocks to the server - default is the Universe" + description = "Allow these CIDR blocks to instance" type = string - default = "0.0.0.0/0" -} - -variable "enable_ssh_connection" { - description = "Enable SSH connection to the server" - type = bool - default = false + default = null } variable "key_name" { diff --git a/modules/bastion/vpc-endpoints.tf b/modules/bastion/vpc-endpoints.tf new file mode 100644 index 0000000..b33ef45 --- /dev/null +++ b/modules/bastion/vpc-endpoints.tf @@ -0,0 +1,37 @@ +module "vpc_endpoints" { + source = "../../modules/vpc-endpoints" + + vpc_id = var.vpc_id + + endpoints = { + ssm = { + service = "ssm" + service_type = "Interface" + security_group_ids = [module.ssm_vpce_sg.security_group_id] + private_dns_enabled = true + subnet_ids = var.private_subnets + policy = null + tags = { Name = "${var.name}-ssm-vpc-endpoint" } + }, + ec2messages = { + service = "ec2messages" + service_type = "Interface" + security_group_ids = [module.ec2messages_vpce_sg.security_group_id] + private_dns_enabled = true + subnet_ids = var.private_subnets + policy = null + tags = { Name = "${var.name}-ec2messages-vpc-endpoint" } + }, + ssmmessages = { + service = "ssmmessages" + service_type = "Interface" + security_group_ids = [module.ssmmessages_vpce_sg.security_group_id] + private_dns_enabled = true + subnet_ids = var.private_subnets + policy = null + tags = { Name = "${var.name}-ssmmessages-vpc-endpoint" } + } + } + + tags = var.tags +}