diff --git a/README.md b/README.md index e35a84f96..a6cf01653 100644 --- a/README.md +++ b/README.md @@ -115,15 +115,15 @@ Upgrades must be executed in step-wise fashion from one version to the next. You | Name | Version | |------|---------| -| [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | ~> 4.6 | +| [terraform](#requirement\_terraform) | ~> 1.0 | +| [aws](#requirement\_aws) | ~> 4.0 | | [kubernetes](#requirement\_kubernetes) | ~> 2.23 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | ~> 4.6 | +| [aws](#provider\_aws) | ~> 4.0 | ## Modules @@ -136,7 +136,9 @@ Upgrades must be executed in step-wise fashion from one version to the next. You | [file\_storage](#module\_file\_storage) | ./modules/file_storage | n/a | | [kms](#module\_kms) | ./modules/kms | n/a | | [networking](#module\_networking) | ./modules/networking | n/a | +| [private\_link](#module\_private\_link) | ./modules/private_link | n/a | | [redis](#module\_redis) | ./modules/redis | n/a | +| [wandb](#module\_wandb) | wandb/wandb/helm | 1.2.0 | ## Resources @@ -157,31 +159,35 @@ Upgrades must be executed in step-wise fashion from one version to the next. You | [create\_bucket](#input\_create\_bucket) | ######################################### External Bucket # ######################################### Most users will not need these settings. They are ment for users who want a bucket and sqs that are in a different account. | `bool` | `true` | no | | [create\_elasticache](#input\_create\_elasticache) | Boolean indicating whether to provision an elasticache instance (true) or not (false). | `bool` | `true` | no | | [create\_vpc](#input\_create\_vpc) | Boolean indicating whether to deploy a VPC (true) or not (false). | `bool` | `true` | no | +| [custom\_domain\_filter](#input\_custom\_domain\_filter) | A custom domain filter to be used by external-dns instead of the default FQDN. If not set, the local FQDN is used. | `string` | `null` | no | | [database\_binlog\_format](#input\_database\_binlog\_format) | Specifies the binlog\_format value to set for the database | `string` | `"ROW"` | no | | [database\_engine\_version](#input\_database\_engine\_version) | Version for MySQL Auora | `string` | `"8.0.mysql_aurora.3.03.0"` | no | | [database\_innodb\_lru\_scan\_depth](#input\_database\_innodb\_lru\_scan\_depth) | Specifies the innodb\_lru\_scan\_depth value to set for the database | `number` | `128` | no | | [database\_instance\_class](#input\_database\_instance\_class) | Instance type to use by database master instance. | `string` | `"db.r5.large"` | no | | [database\_master\_username](#input\_database\_master\_username) | Specifies the master\_username value to set for the database | `string` | `"wandb"` | no | | [database\_name](#input\_database\_name) | Specifies the name of the database | `string` | `"wandb_local"` | no | -| [database\_performance\_insights\_kms\_key\_arn](#input\_database\_performance\_insights\_kms\_key\_arn) | Specifies an existing KMS key ARN to encrypt the performance insights data if performance\_insights\_enabled is was enabled out of band | `string` | n/a | yes | +| [database\_performance\_insights\_kms\_key\_arn](#input\_database\_performance\_insights\_kms\_key\_arn) | Specifies an existing KMS key ARN to encrypt the performance insights data if performance\_insights\_enabled is was enabled out of band | `string` | `null` | no | | [database\_snapshot\_identifier](#input\_database\_snapshot\_identifier) | Specifies whether or not to create this cluster from a snapshot. You can use either the name or ARN when specifying a DB cluster snapshot, or the ARN when specifying a DB snapshot | `string` | `null` | no | | [database\_sort\_buffer\_size](#input\_database\_sort\_buffer\_size) | Specifies the sort\_buffer\_size value to set for the database | `number` | `67108864` | no | | [deletion\_protection](#input\_deletion\_protection) | If the instance should have deletion protection enabled. The database / S3 can't be deleted when this value is set to `true`. | `bool` | `true` | no | | [domain\_name](#input\_domain\_name) | Domain for accessing the Weights & Biases UI. | `string` | n/a | yes | -| [eks\_cluster\_version](#input\_eks\_cluster\_version) | Indicates EKS cluster version | `string` | `"1.21"` | no | +| [eks\_cluster\_version](#input\_eks\_cluster\_version) | EKS cluster kubernetes version | `string` | n/a | yes | | [eks\_policy\_arns](#input\_eks\_policy\_arns) | Additional IAM policy to apply to the EKS cluster | `list(string)` | `[]` | no | | [elasticache\_node\_type](#input\_elasticache\_node\_type) | The type of the redis cache node to deploy | `string` | `"cache.t2.medium"` | no | +| [enable\_dummy\_dns](#input\_enable\_dummy\_dns) | Boolean indicating whether or not to enable dummy DNS for the old alb | `bool` | `false` | no | +| [enable\_operator\_alb](#input\_enable\_operator\_alb) | Boolean indicating whether to use operatore ALB (true) or not (false). | `bool` | `false` | no | | [external\_dns](#input\_external\_dns) | Using external DNS. A `subdomain` must also be specified if this value is true. | `bool` | `false` | no | | [extra\_fqdn](#input\_extra\_fqdn) | n/a | `list(string)` | `[]` | no | | [kms\_key\_alias](#input\_kms\_key\_alias) | KMS key alias for AWS KMS Customer managed key. | `string` | `null` | no | | [kms\_key\_deletion\_window](#input\_kms\_key\_deletion\_window) | Duration in days to destroy the key after it is deleted. Must be between 7 and 30 days. | `number` | `7` | no | | [kms\_key\_policy](#input\_kms\_key\_policy) | The policy that will define the permissions for the kms key. | `string` | `""` | no | -| [kubernetes\_instance\_types](#input\_kubernetes\_instance\_types) | EC2 Instance type for primary node group. | `list(string)` |
[| no | +| [kubernetes\_instance\_types](#input\_kubernetes\_instance\_types) | EC2 Instance type for primary node group. | `list(string)` |
"m4.large"
]
[| no | | [kubernetes\_map\_accounts](#input\_kubernetes\_map\_accounts) | Additional AWS account numbers to add to the aws-auth configmap. | `list(string)` | `[]` | no | | [kubernetes\_map\_roles](#input\_kubernetes\_map\_roles) | Additional IAM roles to add to the aws-auth configmap. |
"m5.large"
]
list(object({| `[]` | no | | [kubernetes\_map\_users](#input\_kubernetes\_map\_users) | Additional IAM users to add to the aws-auth configmap. |
rolearn = string
username = string
groups = list(string)
}))
list(object({| `[]` | no | | [kubernetes\_public\_access](#input\_kubernetes\_public\_access) | Indicates whether or not the Amazon EKS public API server endpoint is enabled. | `bool` | `false` | no | | [kubernetes\_public\_access\_cidrs](#input\_kubernetes\_public\_access\_cidrs) | List of CIDR blocks which can access the Amazon EKS public API server endpoint. | `list(string)` | `[]` | no | +| [license](#input\_license) | Weights & Biases license key. | `string` | n/a | yes | | [namespace](#input\_namespace) | String used for prefix resources. | `string` | n/a | yes | | [network\_cidr](#input\_network\_cidr) | CIDR block for VPC. | `string` | `"10.10.0.0/16"` | no | | [network\_database\_subnet\_cidrs](#input\_network\_database\_subnet\_cidrs) | List of private subnet CIDR ranges to create in VPC. | `list(string)` |
userarn = string
username = string
groups = list(string)
}))
[| no | @@ -192,6 +198,8 @@ Upgrades must be executed in step-wise fashion from one version to the next. You | [network\_private\_subnets](#input\_network\_private\_subnets) | A list of the identities of the private subnetworks in which resources will be deployed. | `list(string)` | `[]` | no | | [network\_public\_subnet\_cidrs](#input\_network\_public\_subnet\_cidrs) | List of private subnet CIDR ranges to create in VPC. | `list(string)` |
"10.10.20.0/24",
"10.10.21.0/24"
]
[| no | | [network\_public\_subnets](#input\_network\_public\_subnets) | A list of the identities of the public subnetworks in which resources will be deployed. | `list(string)` | `[]` | no | +| [other\_wandb\_env](#input\_other\_wandb\_env) | Extra environment variables for W&B | `map(any)` | `{}` | no | +| [private\_link\_allowed\_account\_ids](#input\_private\_link\_allowed\_account\_ids) | List of AWS account IDs allowed to access the VPC Endpoint Service | `list(string)` | `[]` | no | | [public\_access](#input\_public\_access) | Is this instance accessable a public domain. | `bool` | `false` | no | | [ssl\_policy](#input\_ssl\_policy) | SSL policy to use on ALB listener | `string` | `"ELBSecurityPolicy-FS-1-2-Res-2020-10"` | no | | [subdomain](#input\_subdomain) | Subdomain for accessing the Weights & Biases UI. Default creates record at Route53 Route. | `string` | `null` | no | @@ -208,6 +216,8 @@ Upgrades must be executed in step-wise fashion from one version to the next. You | [cluster\_id](#output\_cluster\_id) | n/a | | [cluster\_node\_role](#output\_cluster\_node\_role) | n/a | | [database\_connection\_string](#output\_database\_connection\_string) | n/a | +| [database\_password](#output\_database\_password) | n/a | +| [database\_username](#output\_database\_username) | n/a | | [elasticache\_connection\_string](#output\_elasticache\_connection\_string) | n/a | | [internal\_app\_port](#output\_internal\_app\_port) | n/a | | [kms\_key\_arn](#output\_kms\_key\_arn) | The Amazon Resource Name of the KMS key used to encrypt data at rest. | diff --git a/main.tf b/main.tf index 96bb90c36..5a6798f64 100644 --- a/main.tf +++ b/main.tf @@ -163,6 +163,22 @@ module "app_lb" { network_public_subnets = local.network_public_subnets } +module "private_link" { + count = length(var.private_link_allowed_account_ids) > 0 ? 1 : 0 + source = "./modules/private_link" + + namespace = var.namespace + allowed_account_ids = var.private_link_allowed_account_ids + deletion_protection = var.deletion_protection + network_private_subnets = local.network_private_subnets + alb_name = local.lb_name_truncated + vpc_id = local.network_id + + depends_on = [ + module.wandb + ] +} + resource "aws_autoscaling_attachment" "autoscaling_attachment" { for_each = module.app_eks.autoscaling_group_names autoscaling_group_name = each.value @@ -240,6 +256,7 @@ module "wandb" { ingress = { class = "alb" + additionalHosts = concat(var.extra_fqdn, length(var.private_link_allowed_account_ids) > 0 ? [""] : []) annotations = merge({ "alb.ingress.kubernetes.io/load-balancer-name" = local.lb_name_truncated "alb.ingress.kubernetes.io/inbound-cidrs" = <<-EOF diff --git a/modules/private_link/main.tf b/modules/private_link/main.tf new file mode 100644 index 000000000..b0097437b --- /dev/null +++ b/modules/private_link/main.tf @@ -0,0 +1,57 @@ +locals { + max_lb_name_length = 32 - length("-nlb") + lb_name_truncated = "${substr(var.namespace, 0, local.max_lb_name_length)}-nlb" +} + +resource "aws_lb" "nlb" { + name = local.lb_name_truncated + internal = true + load_balancer_type = "network" + subnets = var.network_private_subnets + enable_deletion_protection = var.deletion_protection +} + +resource "aws_lb_target_group" "nlb" { + name = "${var.namespace}-nlb-tg" + protocol = "TCP" + target_type = "alb" + port = 443 + vpc_id = var.vpc_id + + health_check { + protocol = "HTTPS" + path = "/healthz" + matcher = "200-399" + healthy_threshold = 3 + unhealthy_threshold = 3 + interval = 30 + timeout = 10 + port = "traffic-port" + } +} + +data "aws_lb" "alb" { + name = var.alb_name +} + +resource "aws_lb_target_group_attachment" "nlb_to_alb" { + target_group_arn = aws_lb_target_group.nlb.arn + target_id = data.aws_lb.alb.arn +} + +resource "aws_vpc_endpoint_service" "private_link" { + acceptance_required = false + network_load_balancer_arns = [aws_lb.nlb.arn] + allowed_principals = [for id in var.allowed_account_ids : "arn:aws:iam::${id}:root"] +} + +resource "aws_lb_listener" "nlb" { + load_balancer_arn = aws_lb.nlb.arn + protocol = "TCP" + port = 443 + + default_action { + type = "forward" + target_group_arn = aws_lb_target_group.nlb.arn + } +} diff --git a/modules/private_link/variables.tf b/modules/private_link/variables.tf new file mode 100644 index 000000000..8ba3e5e21 --- /dev/null +++ b/modules/private_link/variables.tf @@ -0,0 +1,29 @@ +variable "namespace" { + description = "Namespace for naming resources" + type = string +} + +variable "allowed_account_ids" { + description = "List of AWS account IDs allowed to access the VPC Endpoint Service" + type = list(string) +} + +variable "network_private_subnets" { + description = "List of private subnets for the VPC" + type = list(string) +} + +variable "deletion_protection" { + description = "If the instance should have deletion protection enabled. The database / S3 can't be deleted when this value is set to `true`." + type = bool +} + +variable "alb_name" { + description = "Name of the ALB to forward NLB traffic to" + type = string +} + +variable "vpc_id" { + description = "ID of the VPC to create the VPC Endpoint Service in" + type = string +} diff --git a/variables.tf b/variables.tf index 8394819f9..52cbfe8c0 100644 --- a/variables.tf +++ b/variables.tf @@ -253,6 +253,11 @@ variable "network_elasticache_subnet_cidrs" { default = ["10.10.30.0/24", "10.10.31.0/24"] } +variable "private_link_allowed_account_ids" { + description = "List of AWS account IDs allowed to access the VPC Endpoint Service" + type = list(string) + default = [] +} ########################################## # EKS Cluster #
"10.10.0.0/24",
"10.10.1.0/24"
]