mirror of
https://github.com/Sea-Haven-Industries/file-share.git
synced 2026-09-30 06:33:17 +00:00
fix(infra): keep the file share off the public internet (PLAT-77)
The instance has no public IP. Office routes use the syslog VPN gateway and other egress uses a NAT gateway. DLM targets the tagged data volume, and replacement detaches stop the instance first.
This commit is contained in:
parent
dadcf1c5ce
commit
cf5efb06ec
6 changed files with 75 additions and 10 deletions
|
|
@ -89,7 +89,9 @@ Prod changes go through HCP Terraform workspace `file-share-prod` (manual apply
|
||||||
|
|
||||||
The management-account CDK workflow no longer runs on push. `workflow_dispatch` remains for an explicit rollback of that stack.
|
The management-account CDK workflow no longer runs on push. `workflow_dispatch` remains for an explicit rollback of that stack.
|
||||||
|
|
||||||
Clients use the private IP. Office routing must include `10.40.20.0/24` on the existing syslog IPsec before SMB from the office will work. A check from `10.10.70.0/24` on 2026-09-28 reached the gateway for `10.40.10.254` and got no hop-1 reply for `10.40.20.1`.
|
The instance has no public IP. Its route table sends `10.10.0.0/16` and `10.30.0.0/16` through the syslog VPN gateway and everything else through a NAT gateway in the syslog public subnet. `10.10.0.0/16` is the Ronkonkoma office LAN and `10.30.0.0/16` is the Locust office LAN, the same pair the syslog VPN already routes. `10.20.0.0/16` is the management VPC and is not routed here.
|
||||||
|
|
||||||
|
Clients use the private IP. Office routing must include `10.40.20.0/24` on the existing syslog IPsec before SMB from the office will work. A check from `10.10.70.0/24` on 2026-09-28 reached the gateway for `10.40.10.254` and got no hop-1 reply for `10.40.20.1`. The nightly DLM policy targets volumes tagged `file-share-backup=true`. Tag the copied volume with that key at cutover.
|
||||||
|
|
||||||
## Expanding Storage
|
## Expanding Storage
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ resource "aws_dlm_lifecycle_policy" "nightly" {
|
||||||
state = "ENABLED"
|
state = "ENABLED"
|
||||||
|
|
||||||
policy_details {
|
policy_details {
|
||||||
resource_types = ["INSTANCE"]
|
resource_types = ["VOLUME"]
|
||||||
|
|
||||||
target_tags = {
|
target_tags = {
|
||||||
"file-share-backup" = "true"
|
"file-share-backup" = "true"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ resource "aws_instance" "this" {
|
||||||
subnet_id = aws_subnet.file_share.id
|
subnet_id = aws_subnet.file_share.id
|
||||||
vpc_security_group_ids = [aws_security_group.file_share.id]
|
vpc_security_group_ids = [aws_security_group.file_share.id]
|
||||||
iam_instance_profile = aws_iam_instance_profile.this.name
|
iam_instance_profile = aws_iam_instance_profile.this.name
|
||||||
associate_public_ip_address = true
|
associate_public_ip_address = false
|
||||||
user_data = local.user_data
|
user_data = local.user_data
|
||||||
user_data_replace_on_change = false
|
user_data_replace_on_change = false
|
||||||
|
|
||||||
|
|
@ -25,12 +25,20 @@ resource "aws_instance" "this" {
|
||||||
Name = "file-share"
|
Name = "file-share"
|
||||||
"file-share-backup" = "true"
|
"file-share-backup" = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
postcondition {
|
||||||
|
condition = self.public_ip == null || self.public_ip == ""
|
||||||
|
error_message = "file-share must not have a public IP."
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_volume_attachment" "data" {
|
resource "aws_volume_attachment" "data" {
|
||||||
count = local.create_instance ? 1 : 0
|
count = local.create_instance ? 1 : 0
|
||||||
|
|
||||||
device_name = "/dev/xvdf"
|
device_name = "/dev/xvdf"
|
||||||
volume_id = var.data_volume_id
|
volume_id = var.data_volume_id
|
||||||
instance_id = aws_instance.this[0].id
|
instance_id = aws_instance.this[0].id
|
||||||
|
stop_instance_before_detaching = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -295,16 +295,27 @@ data "aws_iam_policy_document" "hcptf_apply_services" {
|
||||||
sid = "Ec2Network"
|
sid = "Ec2Network"
|
||||||
effect = "Allow"
|
effect = "Allow"
|
||||||
actions = [
|
actions = [
|
||||||
|
"ec2:AllocateAddress",
|
||||||
|
"ec2:AssociateAddress",
|
||||||
"ec2:AssociateRouteTable",
|
"ec2:AssociateRouteTable",
|
||||||
|
"ec2:CreateNatGateway",
|
||||||
|
"ec2:CreateRoute",
|
||||||
|
"ec2:CreateRouteTable",
|
||||||
"ec2:AuthorizeSecurityGroupEgress",
|
"ec2:AuthorizeSecurityGroupEgress",
|
||||||
"ec2:AuthorizeSecurityGroupIngress",
|
"ec2:AuthorizeSecurityGroupIngress",
|
||||||
"ec2:CreateSecurityGroup",
|
"ec2:CreateSecurityGroup",
|
||||||
"ec2:CreateSubnet",
|
"ec2:CreateSubnet",
|
||||||
"ec2:CreateTags",
|
"ec2:CreateTags",
|
||||||
|
"ec2:DeleteNatGateway",
|
||||||
|
"ec2:DeleteRoute",
|
||||||
|
"ec2:DeleteRouteTable",
|
||||||
"ec2:DeleteSecurityGroup",
|
"ec2:DeleteSecurityGroup",
|
||||||
"ec2:DeleteSubnet",
|
"ec2:DeleteSubnet",
|
||||||
"ec2:DeleteTags",
|
"ec2:DeleteTags",
|
||||||
"ec2:DescribeAccountAttributes",
|
"ec2:DescribeAccountAttributes",
|
||||||
|
"ec2:DescribeAddresses",
|
||||||
|
"ec2:DescribeAddressesAttribute",
|
||||||
|
"ec2:DescribeNatGateways",
|
||||||
"ec2:DescribeAvailabilityZones",
|
"ec2:DescribeAvailabilityZones",
|
||||||
"ec2:DescribeImages",
|
"ec2:DescribeImages",
|
||||||
"ec2:DescribeInstanceAttribute",
|
"ec2:DescribeInstanceAttribute",
|
||||||
|
|
@ -326,7 +337,9 @@ data "aws_iam_policy_document" "hcptf_apply_services" {
|
||||||
"ec2:DescribeVpcAttribute",
|
"ec2:DescribeVpcAttribute",
|
||||||
"ec2:DescribeVpcs",
|
"ec2:DescribeVpcs",
|
||||||
"ec2:DescribeVpnGateways",
|
"ec2:DescribeVpnGateways",
|
||||||
|
"ec2:DisassociateAddress",
|
||||||
"ec2:DisassociateRouteTable",
|
"ec2:DisassociateRouteTable",
|
||||||
|
"ec2:ReleaseAddress",
|
||||||
"ec2:ModifySecurityGroupRules",
|
"ec2:ModifySecurityGroupRules",
|
||||||
"ec2:ModifySubnetAttribute",
|
"ec2:ModifySubnetAttribute",
|
||||||
"ec2:RevokeSecurityGroupEgress",
|
"ec2:RevokeSecurityGroupEgress",
|
||||||
|
|
@ -415,6 +428,8 @@ data "aws_iam_policy_document" "hcptf_plan_refresh" {
|
||||||
effect = "Allow"
|
effect = "Allow"
|
||||||
actions = [
|
actions = [
|
||||||
"ec2:DescribeAccountAttributes",
|
"ec2:DescribeAccountAttributes",
|
||||||
|
"ec2:DescribeAddresses",
|
||||||
|
"ec2:DescribeAddressesAttribute",
|
||||||
"ec2:DescribeAvailabilityZones",
|
"ec2:DescribeAvailabilityZones",
|
||||||
"ec2:DescribeIamInstanceProfileAssociations",
|
"ec2:DescribeIamInstanceProfileAssociations",
|
||||||
"ec2:DescribeImages",
|
"ec2:DescribeImages",
|
||||||
|
|
@ -424,6 +439,7 @@ data "aws_iam_policy_document" "hcptf_plan_refresh" {
|
||||||
"ec2:DescribeInstanceTypes",
|
"ec2:DescribeInstanceTypes",
|
||||||
"ec2:DescribeInstances",
|
"ec2:DescribeInstances",
|
||||||
"ec2:DescribeInternetGateways",
|
"ec2:DescribeInternetGateways",
|
||||||
|
"ec2:DescribeNatGateways",
|
||||||
"ec2:DescribeNetworkInterfaces",
|
"ec2:DescribeNetworkInterfaces",
|
||||||
"ec2:DescribePrefixLists",
|
"ec2:DescribePrefixLists",
|
||||||
"ec2:DescribeRouteTables",
|
"ec2:DescribeRouteTables",
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ data "aws_vpn_gateway" "syslog" {
|
||||||
attached_vpc_id = data.aws_vpc.syslog.id
|
attached_vpc_id = data.aws_vpc.syslog.id
|
||||||
}
|
}
|
||||||
|
|
||||||
data "aws_route_table" "syslog_public" {
|
data "aws_subnet" "syslog_public" {
|
||||||
vpc_id = data.aws_vpc.syslog.id
|
vpc_id = data.aws_vpc.syslog.id
|
||||||
|
|
||||||
filter {
|
filter {
|
||||||
|
|
@ -30,11 +30,50 @@ data "aws_route_table" "syslog_public" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "aws_eip" "nat" {
|
||||||
|
domain = "vpc"
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
Name = "file-share-nat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_nat_gateway" "file_share" {
|
||||||
|
allocation_id = aws_eip.nat.id
|
||||||
|
subnet_id = data.aws_subnet.syslog_public.id
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
Name = "file-share"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route_table" "file_share" {
|
||||||
|
vpc_id = data.aws_vpc.syslog.id
|
||||||
|
|
||||||
|
tags = {
|
||||||
|
Name = "file-share"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route" "office" {
|
||||||
|
for_each = toset(local.office_lan_cidrs)
|
||||||
|
|
||||||
|
route_table_id = aws_route_table.file_share.id
|
||||||
|
destination_cidr_block = each.value
|
||||||
|
gateway_id = data.aws_vpn_gateway.syslog.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_route" "nat" {
|
||||||
|
route_table_id = aws_route_table.file_share.id
|
||||||
|
destination_cidr_block = "0.0.0.0/0"
|
||||||
|
nat_gateway_id = aws_nat_gateway.file_share.id
|
||||||
|
}
|
||||||
|
|
||||||
resource "aws_subnet" "file_share" {
|
resource "aws_subnet" "file_share" {
|
||||||
vpc_id = data.aws_vpc.syslog.id
|
vpc_id = data.aws_vpc.syslog.id
|
||||||
cidr_block = local.subnet_cidr
|
cidr_block = local.subnet_cidr
|
||||||
availability_zone = local.subnet_az
|
availability_zone = local.subnet_az
|
||||||
map_public_ip_on_launch = true
|
map_public_ip_on_launch = false
|
||||||
|
|
||||||
tags = {
|
tags = {
|
||||||
Name = "file-share"
|
Name = "file-share"
|
||||||
|
|
@ -55,5 +94,5 @@ resource "aws_subnet" "file_share" {
|
||||||
|
|
||||||
resource "aws_route_table_association" "file_share" {
|
resource "aws_route_table_association" "file_share" {
|
||||||
subnet_id = aws_subnet.file_share.id
|
subnet_id = aws_subnet.file_share.id
|
||||||
route_table_id = data.aws_route_table.syslog_public.id
|
route_table_id = aws_route_table.file_share.id
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ output "private_ip" {
|
||||||
}
|
}
|
||||||
|
|
||||||
output "public_ip" {
|
output "public_ip" {
|
||||||
description = "Egress address for package install and SSM. Not a client endpoint."
|
description = "Always empty. Egress uses the NAT gateway. Clients use private_ip."
|
||||||
value = one(aws_instance.this[*].public_ip)
|
value = one(aws_instance.this[*].public_ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue