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
127 changes: 103 additions & 24 deletions README.md

Large diffs are not rendered by default.

196 changes: 142 additions & 54 deletions README.yaml

Large diffs are not rendered by default.

134 changes: 109 additions & 25 deletions src/README.md

Large diffs are not rendered by default.

87 changes: 72 additions & 15 deletions src/main.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
locals {
enabled = module.this.enabled

external_vpc_id = var.vpc_id != null ? { "ExternalVpcId" = var.vpc_id } : {}
networking_stack = var.networking_stack != null ? { "NetworkingStack" = var.networking_stack } : {}
subnet_ids = var.subnet_ids != null ? { "ExternalVpcSubnetIds" = var.subnet_ids } : {}
external_security_group_id = var.security_group_id != null ? { "ExternalVpcSecurityGroupId" = var.security_group_id } : {}
created_security_group_id = var.security_group_id == null && var.networking_stack == "external" ? { "ExternalVpcSecurityGroupId" = module.security_group.id } : {}

parameters = merge({
"EC2InstanceCustomPolicy" = module.iam_policy.policy_arn
}, var.parameters)
}, var.parameters
, local.networking_stack
, local.external_vpc_id
, local.subnet_ids
, local.external_security_group_id
, local.created_security_group_id
)

}

Expand Down Expand Up @@ -56,6 +68,29 @@ module "iam_policy" {
]
}

module "security_group" {
source = "cloudposse/security-group/aws"
version = "2.2.0"

enabled = local.enabled && var.security_group_id == null && var.networking_stack == "external"

vpc_id = local.vpc_id

context = module.this.context
}

resource "aws_security_group_rule" "this" {
for_each = var.security_group_rules != null && local.enabled ? { for rule in var.security_group_rules : md5(jsonencode(rule)) => rule } : {}

security_group_id = local.security_group_id

type = each.value.type
from_port = each.value.from_port
to_port = each.value.to_port
protocol = each.value.protocol
cidr_blocks = each.value.cidr_blocks
}

module "cloudformation_stack" {
count = local.enabled ? 1 : 0

Expand All @@ -75,24 +110,46 @@ module "cloudformation_stack" {
depends_on = [module.iam_policy]
}

data "aws_vpc" "this" {
count = local.enabled ? 1 : 0
id = local.vpc_id
}

data "aws_subnets" "private" {
count = local.enabled ? 1 : 0
filter {
name = "vpc-id"
values = [local.vpc_id]
}
filter {
name = "map-public-ip-on-launch"
values = ["false"]
}
}

data "aws_subnets" "public" {
count = local.enabled ? 1 : 0
filter {
name = "vpc-id"
values = [local.vpc_id]
}
filter {
name = "map-public-ip-on-launch"
values = ["true"]
}
}

locals {
vpc_id = one(module.cloudformation_stack[*].outputs["RunsOnVPCId"])
vpc_cidr_block = one(module.cloudformation_stack[*].outputs["RunsOnVpcCidrBlock"])
public_subnet_ids = compact([
one(module.cloudformation_stack[*].outputs["RunsOnPublicSubnet1"]),
one(module.cloudformation_stack[*].outputs["RunsOnPublicSubnet2"]),
one(module.cloudformation_stack[*].outputs["RunsOnPublicSubnet3"]),
])
private_subnet_ids = compact([
one(module.cloudformation_stack[*].outputs["RunsOnPrivateSubnet1"]),
one(module.cloudformation_stack[*].outputs["RunsOnPrivateSubnet2"]),
one(module.cloudformation_stack[*].outputs["RunsOnPrivateSubnet3"]),
])
private_route_table_ids = compact([
vpc_id = var.networking_stack == "embedded" ? one(module.cloudformation_stack[*].outputs["RunsOnVPCId"]) : var.vpc_id
vpc_cidr_block = var.networking_stack == "embedded" ? one(module.cloudformation_stack[*].outputs["RunsOnVpcCidrBlock"]) : one(data.aws_vpc.this[*].cidr_block)
public_subnet_ids = one(data.aws_subnets.public[*].ids)
private_subnet_ids = one(data.aws_subnets.private[*].ids)
private_route_table_ids = var.networking_stack == "embedded" ? compact([
one(module.cloudformation_stack[*].outputs["RunsOnPrivateRouteTable1Id"]),
one(module.cloudformation_stack[*].outputs["RunsOnPrivateRouteTable2Id"]),
one(module.cloudformation_stack[*].outputs["RunsOnPrivateRouteTable3Id"]),
])
]) : []
security_group_id = one(module.cloudformation_stack[*].outputs["RunsOnSecurityGroupId"])
}

data "aws_nat_gateways" "ngws" {
Expand Down
13 changes: 8 additions & 5 deletions src/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,27 @@ output "nat_gateway_ids" {
description = "NAT Gateway IDs"
}

// Required by TGW Component but not created by RunsOn CloudFormation Stack
# Required by TGW Component but not created by RunsOn CloudFormation Stack
output "nat_instance_ids" {
value = []
description = "NAT Instance IDs"
}

output "private_subnet_ids" {
value = local.private_subnet_ids
# value = one(data.aws_subnets.private_subnets[*].ids)
value = local.private_subnet_ids
description = "Private subnet IDs"
}

output "public_subnet_ids" {
value = local.public_subnet_ids
# value = one(data.aws_subnets.public_subnets[*].ids)
value = local.public_subnet_ids
description = "Public subnet IDs"
}

output "security_group_id" {
value = local.security_group_id
description = "Security group ID"
}

output "private_route_table_ids" {
value = local.private_route_table_ids
description = "Private subnet route table IDs"
Expand Down
13 changes: 0 additions & 13 deletions src/remote-state.tf

This file was deleted.

60 changes: 51 additions & 9 deletions src/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,55 @@ variable "policy_body" {
description = "Structure containing the stack policy body"
}

variable "vpc_peering_component" {
default = null
type = object({
component = string
environment = optional(string)
tenant = optional(string)
stage = optional(string)
})
description = "The component name of the VPC Peering Connection"
variable "networking_stack" {
type = string
description = "Let RunsOn manage your networking stack (`embedded`), or use a vpc under your control (`external`). Null will default to whatever the template used as default. If you select `external`, you will need to provide the VPC ID, the subnet IDs, and optionally the security group ID, and make sure your whole networking setup is compatible with RunsOn (see https://runs-on.com/networking/embedded-vs-external/ for more details). To get started quickly, we recommend using the 'embedded' option."
nullable = true
default = "embedded"
validation {
condition = contains(["embedded", "external"], var.networking_stack) || var.networking_stack == null
error_message = "Networking stack must be either `embedded` or `external`."
}
}

variable "vpc_id" {
type = string
description = "VPC ID"
nullable = true
default = null
validation {
condition = var.networking_stack != "external" || var.vpc_id != null
error_message = "VPC ID is required when networking stack is `external`."
}
}

variable "subnet_ids" {
type = list(string)
description = "Subnet IDs"
nullable = true
default = null
validation {
condition = var.networking_stack != "external" || var.subnet_ids != null && length(var.subnet_ids) > 0
error_message = "Subnet IDs are required when networking stack is `external`."
}
}

variable "security_group_id" {
type = string
description = "Security group ID. If not set, a new security group will be created."
nullable = true
default = null
}

variable "security_group_rules" {
type = list(object({
type = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
description = "Security group rules. These are either added to the security passed in, or added to the security group created when var.security_group_id is not set. Types include `ingress` and `egress`."
nullable = true
default = null
}
Loading