Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: (IAC-619) Support VPCs with private and control_plane subnets, NAT gateway is not required #238

Merged
merged 27 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c3bed14
feat: (IAC-619) Support VPCs with ONLY private subnets, NAT gateway i…
dhoucgitter Oct 9, 2023
bfb5cb4
change to support s3 vpc endpoint using Gateway type
dhoucgitter Oct 10, 2023
12989d5
restore create_subnets condition using count iterator, formatting
dhoucgitter Oct 12, 2023
1273ad1
update note to express when nat_id is optional
dhoucgitter Oct 12, 2023
7a091a8
Add a BYON 0 entry to the table
dhoucgitter Oct 16, 2023
a6fee66
Add input variable and document how to enable/disable VPC endpoint cr…
dhoucgitter Oct 17, 2023
9bde720
Add a direct link to referenced BYON scenarios per review comment
dhoucgitter Oct 18, 2023
23cde6e
Add nat_id back to table as optional variable for BYON scenarios 2 & 3
dhoucgitter Oct 18, 2023
de7babf
Update local var name per review comment
dhoucgitter Oct 18, 2023
739ac38
Don't create vpc endpoint SG ingress rule if IaC vpc endpoint creatio…
dhoucgitter Oct 18, 2023
7e0a4a5
any existing security group indicates byo_network_scenario 3 choice, …
dhoucgitter Oct 20, 2023
e952b30
Update ref to local var, allow existing workers SG input without clus…
dhoucgitter Oct 20, 2023
078d5c3
add missing SG description, correct private VPC SG rule description p…
dhoucgitter Oct 20, 2023
ce2cc34
Use private subnets for database when no db subnets provided
dhoucgitter Oct 20, 2023
9c520f7
Add output value Note: to end of BYO network table, required and opti…
dhoucgitter Oct 23, 2023
dd552f8
Add 2 private CIDR config vars and doc for 3 private CIDR variables
dhoucgitter Oct 25, 2023
894f96a
Update ingress rule descriptions
dhoucgitter Oct 25, 2023
1e62eae
Add private_cluster_ingress as dependency to 2 objects for a test
dhoucgitter Oct 26, 2023
6ba5a6c
Use in-line approach for private_cluster_ingress rule
dhoucgitter Oct 26, 2023
c22fdc3
Apply suggested Private Access CIDR edits, Part 1
dhoucgitter Oct 26, 2023
c6e93ca
Add to Private Access CIDR context descriptions per review comment
dhoucgitter Oct 27, 2023
d5997cb
update for review comment
dhoucgitter Oct 27, 2023
9f10b2a
test in-line approach for vpc_endpoint_private_access_cidrs ingress rule
dhoucgitter Oct 27, 2023
4c7c809
fix for previous commit
dhoucgitter Oct 28, 2023
adfae93
remove duplicate commented code
dhoucgitter Oct 30, 2023
4284772
change column header to 'Scenario'
dhoucgitter Oct 31, 2023
250998f
make references to the private, public, and database lists in the sub…
dhoucgitter Oct 31, 2023
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
35 changes: 32 additions & 3 deletions docs/CONFIG-VARS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Supported configuration variables are listed in the tables below. All variables
- [Using Static Credentials](#using-static-credentials)
- [Using AWS Profile](#using-aws-profile)
- [Admin Access](#admin-access)
- [Public Access CIDRs](#public-access-cidrs)
- [Private Access CIDRs](#private-access-cidrs)
- [Networking](#networking)
- [Use Existing](#use-existing)
- [IAM](#iam)
Expand Down Expand Up @@ -72,14 +74,35 @@ NOTE: When deploying infrastructure into a private network (e.g. a VPN), with no

NOTE: The script will either create a new Security Group, or use an existing Security Group, if specified in the `security_group_id` variable.

### Public Access CIDRs

You can use `default_public_access_cidrs` to set a default range for all created resources. To set different ranges for other resources, define the appropriate variable. Use an empty list [] to disallow access explicitly.
dhoucgitter marked this conversation as resolved.
Show resolved Hide resolved

| <div style="width:50px">Name</div> | <div style="width:150px">Description</div> | <div style="width:50px">Type</div> | <div style="width:75px">Default</div> | <div style="width:150px">Notes</div> |
| :--- | :--- | :--- | :--- | :--- |
| default_public_access_cidrs | IP address ranges that are allowed to access all created cloud resources | list of strings | | Set a default for all resources. |
| cluster_endpoint_public_access_cidrs | IP address ranges that are allowed to access the AKS cluster API | list of strings | | For client admin access to the cluster api (by kubectl, for example). Only used with `cluster_api_mode=public` |
| cluster_endpoint_public_access_cidrs | IP address ranges that are allowed to access the EKS cluster API | list of strings | | For client admin access to the cluster api (by kubectl, for example). Only used with `cluster_api_mode=public` |
| vm_public_access_cidrs | IP address ranges that are allowed to access the VMs | list of strings | | Opens port 22 for SSH access to the jump server and/or NFS VM by adding Ingress Rule on the Security Group. Only used with `create_jump_public_ip=true` or `create_nfs_public_ip=true`. |
| postgres_access_cidrs | IP address ranges that are allowed to access the AWS PostgreSQL server | list of strings || Opens port 5432 by adding Ingress Rule on the Security Group. Only used when creating postgres instances.|
| postgres_public_access_cidrs | IP address ranges that are allowed to access the AWS PostgreSQL server | list of strings || Opens port 5432 by adding Ingress Rule on the Security Group. Only used when creating postgres instances.|

### Private Access CIDRs

For resources accessible at private IP addresses only, it may be necessary, depending upon your networking configuration, to specify additional CIDRs for clients requiring access to those resources. There are three private access CIDR variables provided so that you may specify distinct IP ranges needing access for each of the three different contexts:

1. Cluster API Server Endpoint is Private - use `cluster_endpoint_private_access_cidrs` to indicate the client IP ranges needing access
2. Jump or NFS Server VMs have only private IPs - use `vm_private_access_cidrs` to indicate the IP ranges for the DAC client VM needing access. DAC's baseline module will require SSH access to the Jump VM and/or NFS Server VM.
3. VPC has no public egress - use `vpc_endpoint_private_access_cidrs` to allow access to AWS private link services required to build the cluster, e.g. EC2.

For example, with a cluster API server endpoint that is private, the IAC client VM must have API server endpoint access during cluster creation to perform a health check. If your IAC client VM is not in your private subnet, its IP or CIDR range should be present in `cluster_endpoint_private_access_cidrs`.

You can also use `default_private_access_cidrs` to apply the same CIDR range to all three private contexts. To set different CIDR ranges for a specific private context, set the appropriate variable. Use an empty list [] to disallow access explicitly.

| <div style="width:50px">Name</div> | <div style="width:150px">Description</div> | <div style="width:50px">Type</div> | <div style="width:75px">Default</div> | <div style="width:150px">Notes</div> |
| :--- | :--- | :--- | :--- | :--- |
| default_private_access_cidrs | IP address ranges that are allowed to access all created private cloud resources | list of strings | | Set a list of CIDR ranges that will be applied as a default value for `cluster_endpoint_private_access_cidrs`, `vpc_endpoint_private_access_cidrs` and `vm_private_access_cidrs`. **Note:** If you need to set distinct IP CIDR ranges for any of these contexts, use the specific variables below rather than this one. |
| cluster_endpoint_private_access_cidrs | IP address ranges that are allowed to access the EKS cluster API Server endpoint| list of strings | | For clients needing access to the cluster api server endpoint (e.g. for VMs running terraform apply and for VMs where admins will use kubectl). Only used with `cluster_api_mode=private` |
| vpc_endpoint_private_access_cidrs | IP address ranges that are allowed to access all AWS Services targeted by the VPC endpoints | list of strings | | Adds an ingress rule to the auxiliary security group (_prefix_-sg) protecting the VPC Endpoints, allowing HTTPS access at port 443. Only used with `vpc_private_endpoints_enabled=true`. |
| vm_private_access_cidrs | IP address ranges that are allowed to access private IP based Jump or NFS Server VMs.| list of strings | | Opens port 22 for SSH access to the jump server and/or NFS VM by adding Ingress Rule on the Workers Security Group. Only used with `create_jump_public_ip=false` or `create_nfs_public_ip=false`. |

## Networking
| Name | Description | Type | Default | Notes |
Expand Down Expand Up @@ -109,7 +132,7 @@ The variables in the table below can be used to define the existing resources. R
| :--- | ---: | ---: | ---: | ---: |
| vpc_id | ID of existing VPC | string | null | Only required if deploying into existing VPC. |
| subnet_ids | List of existing subnets mapped to desired usage | map(string) | {} | Only required if deploying into existing subnets. |
| nat_id | ID of existing AWS NAT gateway | string | null | Only required if deploying into existing VPC and subnets. |
| nat_id | ID of existing AWS NAT gateway | string | null | Optional if deploying into existing VPC and subnets for [BYON scenarios 2 & 3](./user/BYOnetwork.md#supported-scenarios-and-requirements-for-using-existing-network-resources)|
| security_group_id | ID of existing Security Group that controls external access to Jump/NFS VMs and Postgres | string | null | Only required if using existing Security Group. See [Security Group](./user/BYOnetwork.md#external-access-security-group) for requirements. |
| cluster_security_group_id | ID of existing Security Group that controls Pod access to the control plane | string | null | Only required if using existing Cluster Security Group. See [Cluster Security Group](./user/BYOnetwork.md#cluster-security-group) for requirements.|
| workers_security_group_id | ID of existing Security Group that allows access between node VMs, Jump VM, and data sources (nfs, efs, postges) | string | null | Only required if using existing Security Group for Node Group VMs. See [Workers Security Group](./user/BYOnetwork.md#workers-security-group) for requirements. |
Expand All @@ -124,6 +147,12 @@ subnet_ids = {
}
```

### VPC Endpoints
| Name | Description | Type | Default | Notes |
| :--- | ---: | ---: | ---: | ---: |
| vpc_private_endpoints_enabled | Enable the creation of VPC private endpoints | bool | true | Setting to false prevents IaC from creating and managing VPC private endpoints in the cluster |


## IAM

By default, two custom IAM policies and two custom IAM roles (with instance profiles) are created. If your site security protocol does not allow for automatic creation of IAM resources, you can provide pre-created roles using the following options:
Expand Down
16 changes: 9 additions & 7 deletions docs/user/BYOnetwork.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ You have the option to use existing network resources with SAS Viya 4 Terraform

**NOTE:** We refer to the use of existing resources as "bring your own" or "BYO" resources.

| Scenario|Required Variables|Additional Requirements|Resources to be Created|
| :--- | :--- | :--- | :--- |
| 1. To work with an existing VPC | `vpc_id` | <ul><li>VPC does not contain any Subnets or other [Network components](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Networking.html)</li><li>VPC block size must be IPv4 with '/16' netmask (supports 65,536 IP addresses)</li><li>`DNS hostnames` and `DNS resolution` are enabled</li><li>[`subnets`](../CONFIG-VARS.md#networking) CIDR blocks must match with VPC IPv4 CIDR block</li></ul> | Subnets, NAT Gateway and Security Group|
| 2. To configure all components of your VPC network - Subnets, Routes & associations, Internet and NAT Gateways | `vpc_id`, <br>`subnet_ids` and <br>`nat_id` | <ul><li>all requirements from Scenario #1</li><li>Subnets Availability Zones must be within the [location](../CONFIG-VARS.md#required-variables)</li><li>AWS Tags with `<prefix>` value replaced with the [prefix](../CONFIG-VARS.md#required-variables) input value for <br>- Public Subnets:<ul><li>`{"kubernetes.io/role/elb"="1"}`</li><li>`{"kubernetes.io/cluster/<prefix>-eks"="shared"}`</li></ul>-Private Subnets:<ul><li>`{"kubernetes.io/role/internal-elb"="1"}`</li><li>`{"kubernetes.io/cluster/<prefix>-eks"="shared"}`</li></ul>See [AWS docs](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html) for background on subnet tag requirements to match EKS Cluster name| Security Group |
| 3. To configure all components of your VPC network and Security Groups | `vpc_id`,<br>`subnet_ids`, <br>`nat_id`, <br>`security_group_id`, <br>`cluster_security_group_id`, and <br>`workers_security_group_id` |<ul><li>all requirements from Scenarios #2 and [these pre-defined Security Groups](#security-groups)</li></ul>| None |
|Scenario |Description|Required Variables|Optional Variables|Additional Requirements|Resources to be Created|
| -: | :--- | :--- | :--- | :--- | :---|
| 0|No existing network resources | None | | Not a BYO network scenario | IaC creates the required network resources |
| 1|To work with an existing VPC | `vpc_id` | | <ul><li>VPC does not contain any Subnets or other [Network components](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Networking.html)</li><li>VPC block size must be IPv4 with '/16' netmask (supports 65,536 IP addresses)</li><li>`DNS hostnames` and `DNS resolution` are enabled</li><li>[`subnets`](../CONFIG-VARS.md#networking) CIDR blocks must match with VPC IPv4 CIDR block</li></ul> | Subnets, NAT Gateway and Security Groups|
| 2|To configure all components of your VPC network - Subnets, Routes & associations and optionally Internet and NAT Gateways | `vpc_id`,<br>`private` subnet list within the [subnet_ids](../CONFIG-VARS.md#use-existing) map| `nat_id`, <br>`public` and `database` subnet lists within the [subnet_ids](../CONFIG-VARS.md#use-existing) map | <ul><li>all requirements from Scenario #1</li><li>Subnets Availability Zones must be within the [location](../CONFIG-VARS.md#required-variables)</li><li>AWS Tags with `<prefix>` value replaced with the [prefix](../CONFIG-VARS.md#required-variables) input value for <br>- Public Subnets:<ul><li>`{"kubernetes.io/role/elb"="1"}`</li><li>`{"kubernetes.io/cluster/<prefix>-eks"="shared"}`</li></ul>-Private Subnets:<ul><li>`{"kubernetes.io/role/internal-elb"="1"}`</li><li>`{"kubernetes.io/cluster/<prefix>-eks"="shared"}`</li></ul>See [AWS docs](https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html) for background on subnet tag requirements to match EKS Cluster name| Security Groups |
| 3|To configure all components of your VPC network and Security Groups and optionally Internet and NAT Gateways| `vpc_id`,<br>`private` subnet list within the [subnet_ids](../CONFIG-VARS.md#use-existing) map, <br>`security_group_id`, <br>`cluster_security_group_id`, and <br>`workers_security_group_id` | `nat_id`, <br>`public` and `database` subnet lists within the [subnet_ids](../CONFIG-VARS.md#use-existing) map |<ul><li>all requirements from Scenarios #2 and [these pre-defined Security Groups](#security-groups)</li></ul>| None |

**Note**: The `byo_network_scenario` IAC output value is informational only and is intended to convey the BYO network scenario that IAC has selected according to the [Use Existing](../CONFIG-VARS.md#use-existing) input variable values provided to IAC.

### Security Groups

Expand Down Expand Up @@ -50,9 +52,9 @@ For more information on these Security Groups, please see https://docs.aws.amazo

When creating your BYO Network resources you should consult with your Network Administrator and use any of these methods to create a working AWS VPC Network:
- [AWS QuickStarts for VPC](https://aws.amazon.com/quickstart/architecture/vpc/)
- See the "simple-vpc" and "complete-vpc" examples in [terraform-aws-vpc module](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples)
- See the "simple-vpc" and "complete-vpc" examples in [terraform-aws-vpc module](https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master/examples)

AWS documentation for reference:
AWS documentation for reference:
- [How Amazon VPC works](https://docs.aws.amazon.com/vpc/latest/userguide/how-it-works.html)
- [VPC and subnet sizing for IPv4](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Subnets.html#vpc-sizing-ipv4)

Expand Down
25 changes: 17 additions & 8 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ locals {
aws_caller_identity_user_name = element(split("/", data.aws_caller_identity.terraform.arn), length(split("/", data.aws_caller_identity.terraform.arn)) - 1)

# General
security_group_id = var.security_group_id == null ? aws_security_group.sg[0].id : data.aws_security_group.sg[0].id
sec_group = coalescelist(aws_security_group.sg_a, aws_security_group.sg_b)
security_group_id = var.security_group_id == null ? local.sec_group[0].id : data.aws_security_group.sg[0].id
cluster_security_group_id = var.cluster_security_group_id == null ? aws_security_group.cluster_security_group[0].id : var.cluster_security_group_id
workers_security_group_id = var.workers_security_group_id == null ? aws_security_group.workers_security_group[0].id : var.workers_security_group_id
cluster_name = "${var.prefix}-eks"
Expand All @@ -20,11 +21,19 @@ locals {
aws_shared_credentials = local.use_aws_shared_credentials_file ? [var.aws_shared_credentials_file] : var.aws_shared_credentials_files

# CIDRs
default_public_access_cidrs = var.default_public_access_cidrs == null ? [] : var.default_public_access_cidrs
vm_public_access_cidrs = var.vm_public_access_cidrs == null ? local.default_public_access_cidrs : var.vm_public_access_cidrs
cluster_endpoint_public_access_cidrs = var.cluster_api_mode == "private" ? [] : (var.cluster_endpoint_public_access_cidrs == null ? local.default_public_access_cidrs : var.cluster_endpoint_public_access_cidrs)
cluster_endpoint_private_access_cidrs = var.cluster_endpoint_private_access_cidrs == null ? distinct(concat(module.vpc.public_subnet_cidrs, module.vpc.private_subnet_cidrs)) : var.cluster_endpoint_private_access_cidrs # tflint-ignore: terraform_unused_declarations
postgres_public_access_cidrs = var.postgres_public_access_cidrs == null ? local.default_public_access_cidrs : var.postgres_public_access_cidrs
default_public_access_cidrs = var.default_public_access_cidrs == null ? [] : var.default_public_access_cidrs
default_private_access_cidrs = var.default_private_access_cidrs == null ? [] : var.default_private_access_cidrs

vm_public_access_cidrs = var.vm_public_access_cidrs == null ? local.default_public_access_cidrs : var.vm_public_access_cidrs
vm_private_access_cidrs = var.vm_private_access_cidrs == null ? local.default_private_access_cidrs : var.vm_private_access_cidrs

cluster_endpoint_public_access_cidrs = var.cluster_api_mode == "private" ? [] : (var.cluster_endpoint_public_access_cidrs == null ? local.default_public_access_cidrs : var.cluster_endpoint_public_access_cidrs)

cluster_endpoint_private_access_cidrs = var.cluster_api_mode == "public" ? [] : var.cluster_endpoint_private_access_cidrs == null ? distinct(concat(module.vpc.public_subnet_cidrs, module.vpc.private_subnet_cidrs, local.default_private_access_cidrs)) : distinct(concat(module.vpc.public_subnet_cidrs, module.vpc.private_subnet_cidrs, local.default_private_access_cidrs, var.cluster_endpoint_private_access_cidrs)) # tflint-ignore: terraform_unused_declarations

vpc_endpoint_private_access_cidrs = var.vpc_endpoint_private_access_cidrs == null ? distinct(concat(module.vpc.public_subnet_cidrs, module.vpc.private_subnet_cidrs, local.default_private_access_cidrs)) : distinct(concat(module.vpc.public_subnet_cidrs, module.vpc.private_subnet_cidrs, local.default_private_access_cidrs, var.vpc_endpoint_private_access_cidrs))

postgres_public_access_cidrs = var.postgres_public_access_cidrs == null ? local.default_public_access_cidrs : var.postgres_public_access_cidrs

# Subnets
jump_vm_subnet = var.create_jump_public_ip ? module.vpc.public_subnets[0] : module.vpc.private_subnets[0]
Expand Down Expand Up @@ -89,7 +98,7 @@ locals {
tags = var.autoscaling_enabled ? merge(local.tags, { key = "k8s.io/cluster-autoscaler/${local.cluster_name}", value = "owned", propagate_at_launch = true }, { key = "k8s.io/cluster-autoscaler/enabled", value = "true", propagate_at_launch = true }) : local.tags
# Node Pool IAM Configuration
iam_role_use_name_prefix = false
iam_role_name = "${var.prefix}-default-eks-node-group"
iam_role_name = "${var.prefix}-default-eks-node-group"
}
}
Expand Down Expand Up @@ -138,7 +147,7 @@ locals {
tags = var.autoscaling_enabled ? merge(local.tags, { key = "k8s.io/cluster-autoscaler/${local.cluster_name}", value = "owned", propagate_at_launch = true }, { key = "k8s.io/cluster-autoscaler/enabled", value = "true", propagate_at_launch = true }) : local.tags
# Node Pool IAM Configuration
iam_role_use_name_prefix = false
iam_role_name = "${var.prefix}-${key}-eks-node-group"
iam_role_name = "${var.prefix}-${key}-eks-node-group"
}
}
Expand Down
Loading