From 2b3eecb109cba0936b1181482fe0a1636e613461 Mon Sep 17 00:00:00 2001 From: Vladimir <26582191+SweetOps@users.noreply.github.com> Date: Tue, 15 Jun 2021 20:03:29 +0300 Subject: [PATCH] feat: use security-group module instead of resource (#114) --- README.md | 78 ++++++++++++++++++++++++------ README.yaml | 56 +++++++++++++++++++-- docs/terraform.md | 14 +++--- main.tf | 4 +- outputs.tf | 6 +-- sg.tf | 57 ++++------------------ test/src/examples_complete_test.go | 10 ++++ variables.tf | 49 ++++++++++++++----- 8 files changed, 182 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index 2b94d92c..6db85afa 100644 --- a/README.md +++ b/README.md @@ -229,9 +229,28 @@ Other examples: kubernetes_version = var.kubernetes_version oidc_provider_enabled = false - - workers_security_group_ids = [module.eks_workers.security_group_id] - workers_role_arns = [module.eks_workers.workers_role_arn] + workers_role_arns = [module.eks_workers.workers_role_arn] + + security_group_rules = [ + { + type = "egress" + from_port = 0 + to_port = 65535 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + source_security_group_id = null + description = "Allow all outbound traffic" + }, + { + type = "ingress" + from_port = 0 + to_port = 65535 + protocol = "-1" + cidr_blocks = [] + source_security_group_id = module.eks_workers.security_group_id + description = "Allow all inbound traffic from EKS workers Security Group" + } + ] } ``` @@ -306,9 +325,36 @@ Module usage with two worker groups: kubernetes_version = var.kubernetes_version oidc_provider_enabled = false - - workers_role_arns = [module.eks_workers.workers_role_arn, module.eks_workers_2.workers_role_arn] - workers_security_group_ids = [module.eks_workers.security_group_id, module.eks_workers_2.security_group_id] + workers_role_arns = [module.eks_workers.workers_role_arn, module.eks_workers_2.workers_role_arn] + + security_group_rules = [ + { + type = "egress" + from_port = 0 + to_port = 65535 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + source_security_group_id = null + description = "Allow all outbound traffic" + }, + { + type = "ingress" + from_port = 0 + to_port = 65535 + protocol = "-1" + cidr_blocks = [] + source_security_group_id = module.eks_workers.security_group_id + description = "Allow all inbound traffic from EKS workers Security Group" + }, + { + type = "ingress" + from_port = 0 + to_port = 65535 + protocol = "-1" + cidr_blocks = [] + source_security_group_id = module.eks_workers_2.security_group_id + description = "Allow all inbound traffic from EKS workers Security Group" + } } ``` @@ -356,6 +402,7 @@ Available targets: | Name | Source | Version | |------|--------|---------| | [label](#module\_label) | cloudposse/label/null | 0.24.1 | +| [security\_group](#module\_security\_group) | cloudposse/security-group/aws | 0.3.1 | | [this](#module\_this) | cloudposse/label/null | 0.24.1 | ## Resources @@ -371,11 +418,6 @@ Available targets: | [aws_iam_role_policy_attachment.amazon_eks_service_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_kms_alias.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | | [aws_kms_key.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | -| [aws_security_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | -| [aws_security_group_rule.egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_cidr_blocks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_workers](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | | [kubernetes_config_map.aws_auth](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map) | resource | | [kubernetes_config_map.aws_auth_ignore_changes](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map) | resource | | [null_resource.wait_for_cluster](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | @@ -391,8 +433,6 @@ Available targets: | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [additional\_tag\_map](#input\_additional\_tag\_map) | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no | -| [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | List of CIDR blocks to be allowed to connect to the EKS cluster | `list(string)` | `[]` | no | -| [allowed\_security\_groups](#input\_allowed\_security\_groups) | List of Security Group IDs to be allowed to connect to the EKS cluster | `list(string)` | `[]` | no | | [apply\_config\_map\_aws\_auth](#input\_apply\_config\_map\_aws\_auth) | Whether to apply the ConfigMap to allow worker nodes to join the EKS cluster and allow additional users, accounts and roles to acces the cluster | `bool` | `true` | no | | [attributes](#input\_attributes) | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no | | [cluster\_encryption\_config\_enabled](#input\_cluster\_encryption\_config\_enabled) | Set to `true` to enable Cluster Encryption Configuration | `bool` | `true` | no | @@ -426,13 +466,17 @@ Available targets: | [public\_access\_cidrs](#input\_public\_access\_cidrs) | Indicates which CIDR blocks can access the Amazon EKS public API server endpoint when enabled. EKS defaults this to a list with 0.0.0.0/0. | `list(string)` |
[| no | | [regex\_replace\_chars](#input\_regex\_replace\_chars) | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.
"0.0.0.0/0"
]
[| no | +| [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Whether to create a default Security Group with unique name beginning with the normalized prefix. | `bool` | `false` | no | +| [security\_groups](#input\_security\_groups) | A list of Security Group IDs to associate with EKS cluster. | `list(string)` | `[]` | no | | [stage](#input\_stage) | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs to launch the cluster in | `list(string)` | n/a | yes | | [tags](#input\_tags) | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | VPC ID for the EKS cluster | `string` | n/a | yes | | [wait\_for\_cluster\_command](#input\_wait\_for\_cluster\_command) | `local-exec` command to execute to determine if the EKS cluster is healthy. Cluster endpoint are available as environment variable `ENDPOINT` | `string` | `"curl --silent --fail --retry 60 --retry-delay 5 --retry-connrefused --insecure --output /dev/null $ENDPOINT/healthz"` | no | | [workers\_role\_arns](#input\_workers\_role\_arns) | List of Role ARNs of the worker nodes | `list(string)` | `[]` | no | -| [workers\_security\_group\_ids](#input\_workers\_security\_group\_ids) | Security Group IDs of the worker nodes | `list(string)` | `[]` | no | ## Outputs @@ -611,8 +655,8 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply ### Contributors -| [![Erik Osterman][osterman_avatar]][osterman_homepage]
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": "Allow all outbound traffic",
"from_port": 0,
"protocol": "-1",
"to_port": 65535,
"type": "egress"
}
]
[| no | | [regex\_replace\_chars](#input\_regex\_replace\_chars) | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.
"0.0.0.0/0"
]
[| no | +| [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Whether to create a default Security Group with unique name beginning with the normalized prefix. | `bool` | `false` | no | +| [security\_groups](#input\_security\_groups) | A list of Security Group IDs to associate with EKS cluster. | `list(string)` | `[]` | no | | [stage](#input\_stage) | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs to launch the cluster in | `list(string)` | n/a | yes | | [tags](#input\_tags) | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | VPC ID for the EKS cluster | `string` | n/a | yes | | [wait\_for\_cluster\_command](#input\_wait\_for\_cluster\_command) | `local-exec` command to execute to determine if the EKS cluster is healthy. Cluster endpoint are available as environment variable `ENDPOINT` | `string` | `"curl --silent --fail --retry 60 --retry-delay 5 --retry-connrefused --insecure --output /dev/null $ENDPOINT/healthz"` | no | | [workers\_role\_arns](#input\_workers\_role\_arns) | List of Role ARNs of the worker nodes | `list(string)` | `[]` | no | -| [workers\_security\_group\_ids](#input\_workers\_security\_group\_ids) | Security Group IDs of the worker nodes | `list(string)` | `[]` | no | ## Outputs diff --git a/main.tf b/main.tf index c7df573f..d636e473 100644 --- a/main.tf +++ b/main.tf @@ -5,6 +5,8 @@ locals { resources = var.cluster_encryption_config_resources provider_key_arn = local.enabled && var.cluster_encryption_config_enabled && var.cluster_encryption_config_kms_key_id == "" ? join("", aws_kms_key.cluster.*.arn) : var.cluster_encryption_config_kms_key_id } + + security_group_enabled = module.this.enabled && var.security_group_enabled } module "label" { @@ -61,7 +63,7 @@ resource "aws_eks_cluster" "default" { } vpc_config { - security_group_ids = [join("", aws_security_group.default.*.id)] + security_group_ids = compact(concat(module.security_group.*.id, var.security_groups)) subnet_ids = var.subnet_ids endpoint_private_access = var.endpoint_private_access endpoint_public_access = var.endpoint_public_access diff --git a/outputs.tf b/outputs.tf index 2bd21a8a..d135ac0a 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,16 +1,16 @@ output "security_group_id" { description = "ID of the EKS cluster Security Group" - value = join("", aws_security_group.default.*.id) + value = module.security_group.id } output "security_group_arn" { description = "ARN of the EKS cluster Security Group" - value = join("", aws_security_group.default.*.arn) + value = module.security_group.arn } output "security_group_name" { description = "Name of the EKS cluster Security Group" - value = join("", aws_security_group.default.*.name) + value = module.security_group.name } output "eks_cluster_id" { diff --git a/sg.tf b/sg.tf index e16e7904..6617c069 100644 --- a/sg.tf +++ b/sg.tf @@ -1,51 +1,12 @@ -resource "aws_security_group" "default" { - count = local.enabled ? 1 : 0 - name = module.label.id - description = "Security Group for EKS cluster" - vpc_id = var.vpc_id - tags = module.label.tags -} - -resource "aws_security_group_rule" "egress" { - count = local.enabled ? 1 : 0 - description = "Allow all egress traffic" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - security_group_id = join("", aws_security_group.default.*.id) - type = "egress" -} +module "security_group" { + source = "cloudposse/security-group/aws" + version = "0.3.1" -resource "aws_security_group_rule" "ingress_workers" { - count = local.enabled ? length(var.workers_security_group_ids) : 0 - description = "Allow the cluster to receive communication from the worker nodes" - from_port = 0 - to_port = 65535 - protocol = "-1" - source_security_group_id = var.workers_security_group_ids[count.index] - security_group_id = join("", aws_security_group.default.*.id) - type = "ingress" -} - -resource "aws_security_group_rule" "ingress_security_groups" { - count = local.enabled ? length(var.allowed_security_groups) : 0 - description = "Allow inbound traffic from existing Security Groups" - from_port = 0 - to_port = 65535 - protocol = "-1" - source_security_group_id = var.allowed_security_groups[count.index] - security_group_id = join("", aws_security_group.default.*.id) - type = "ingress" -} + use_name_prefix = var.security_group_use_name_prefix + rules = var.security_group_rules + description = var.security_group_description + vpc_id = var.vpc_id -resource "aws_security_group_rule" "ingress_cidr_blocks" { - count = local.enabled && length(var.allowed_cidr_blocks) > 0 ? 1 : 0 - description = "Allow inbound traffic from CIDR blocks" - from_port = 0 - to_port = 65535 - protocol = "-1" - cidr_blocks = var.allowed_cidr_blocks - security_group_id = join("", aws_security_group.default.*.id) - type = "ingress" + enabled = local.security_group_enabled + context = module.label.context } diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index 4bc7f91a..04541fc9 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -106,6 +106,16 @@ func TestExamplesComplete(t *testing.T) { // Verify we're getting back the outputs we expect assert.Equal(t, "eg-test-eks-"+randId+"-cluster", eksClusterSecurityGroupName) + // Run `terraform output` to get the value of an output variable + eksClusterSecurityGroupID := terraform.Output(t, terraformOptions, "eks_cluster_security_group_id") + // Verify we're getting back the outputs we expect + assert.Contains(t, eksClusterSecurityGroupID, "sg-", "SG ID should contains substring 'sg-'") + + // Run `terraform output` to get the value of an output variable + eksClusterSecurityGroupARN := terraform.Output(t, terraformOptions, "eks_cluster_security_group_arn") + // Verify we're getting back the outputs we expect + assert.Contains(t, eksClusterSecurityGroupARN, "arn:aws:ec2", "SG ID should contains substring 'arn:aws:ec2'") + // Run `terraform output` to get the value of an output variable eksNodeGroupId := terraform.Output(t, terraformOptions, "eks_node_group_id") // Verify we're getting back the outputs we expect diff --git a/variables.tf b/variables.tf index b490b73b..0764be3c 100644 --- a/variables.tf +++ b/variables.tf @@ -13,27 +13,52 @@ variable "subnet_ids" { type = list(string) } -variable "allowed_security_groups" { - type = list(string) - default = [] - description = "List of Security Group IDs to be allowed to connect to the EKS cluster" +variable "security_group_enabled" { + type = bool + description = "Whether to create default Security Group for EKS cluster." + default = true } -variable "allowed_cidr_blocks" { - type = list(string) - default = [] - description = "List of CIDR blocks to be allowed to connect to the EKS cluster" +variable "security_group_description" { + type = string + default = "Security Group for EKS cluster" + description = "The Security Group description." } -variable "workers_role_arns" { +variable "security_group_use_name_prefix" { + type = bool + default = false + description = "Whether to create a default Security Group with unique name beginning with the normalized prefix." +} + +variable "security_group_rules" { + type = list(any) + default = [ + { + type = "egress" + from_port = 0 + to_port = 65535 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + description = "Allow all outbound traffic" + } + ] + description = <<-EOT + A list of maps of Security Group rules. + The values of map is fully complated with `aws_security_group_rule` resource. + To get more info see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule . + EOT +} + +variable "security_groups" { type = list(string) - description = "List of Role ARNs of the worker nodes" default = [] + description = "A list of Security Group IDs to associate with EKS cluster." } -variable "workers_security_group_ids" { +variable "workers_role_arns" { type = list(string) - description = "Security Group IDs of the worker nodes" + description = "List of Role ARNs of the worker nodes" default = [] }
{
"cidr_blocks": [
"0.0.0.0/0"
],
"description": "Allow all outbound traffic",
"from_port": 0,
"protocol": "-1",
"to_port": 65535,
"type": "egress"
}
]