From bd780930b01716affdef7f417c5231fec50864a3 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Mon, 8 Sep 2025 21:33:05 +0100 Subject: [PATCH 1/2] Add terraform-aws-ingress module Signed-off-by: Jim Enright --- README.md | 1 + .../.terraform-docs.yaml | 21 ++ modules/terraform-aws-ingress/README.md | 82 ++++++++ modules/terraform-aws-ingress/data.tf | 30 +++ modules/terraform-aws-ingress/defaults.tf | 32 +++ .../doc_fragments/header.md | 14 ++ .../examples/ex01-minimal_inputs/main.tf | 50 +++++ .../examples/ex01-minimal_inputs/outputs.tf | 37 ++++ .../terraform.tfvars.sample | 30 +++ .../examples/ex01-minimal_inputs/variables.tf | 45 +++++ .../examples/ex02-existing_sgs/main.tf | 68 +++++++ .../examples/ex02-existing_sgs/outputs.tf | 37 ++++ .../ex02-existing_sgs/terraform.tfvars.sample | 30 +++ .../examples/ex02-existing_sgs/variables.tf | 45 +++++ modules/terraform-aws-ingress/main.tf | 190 ++++++++++++++++++ modules/terraform-aws-ingress/outputs.tf | 44 ++++ modules/terraform-aws-ingress/provider.tf | 24 +++ modules/terraform-aws-ingress/variables.tf | 127 ++++++++++++ modules/terraform-cdp-aws-pre-reqs/README.md | 12 +- .../terraform-cdp-aws-pre-reqs/defaults.tf | 8 +- modules/terraform-cdp-aws-pre-reqs/main.tf | 89 +------- modules/terraform-cdp-aws-pre-reqs/outputs.tf | 4 +- .../terraform-cdp-aws-pre-reqs/variables.tf | 30 ++- 23 files changed, 956 insertions(+), 94 deletions(-) create mode 100644 modules/terraform-aws-ingress/.terraform-docs.yaml create mode 100644 modules/terraform-aws-ingress/README.md create mode 100644 modules/terraform-aws-ingress/data.tf create mode 100644 modules/terraform-aws-ingress/defaults.tf create mode 100644 modules/terraform-aws-ingress/doc_fragments/header.md create mode 100644 modules/terraform-aws-ingress/examples/ex01-minimal_inputs/main.tf create mode 100644 modules/terraform-aws-ingress/examples/ex01-minimal_inputs/outputs.tf create mode 100644 modules/terraform-aws-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample create mode 100644 modules/terraform-aws-ingress/examples/ex01-minimal_inputs/variables.tf create mode 100644 modules/terraform-aws-ingress/examples/ex02-existing_sgs/main.tf create mode 100644 modules/terraform-aws-ingress/examples/ex02-existing_sgs/outputs.tf create mode 100644 modules/terraform-aws-ingress/examples/ex02-existing_sgs/terraform.tfvars.sample create mode 100644 modules/terraform-aws-ingress/examples/ex02-existing_sgs/variables.tf create mode 100644 modules/terraform-aws-ingress/main.tf create mode 100644 modules/terraform-aws-ingress/outputs.tf create mode 100644 modules/terraform-aws-ingress/provider.tf create mode 100644 modules/terraform-aws-ingress/variables.tf diff --git a/README.md b/README.md index 9ab0281..b63c8d4 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ This repository contains a number of Terraform modules for creation of the pre-r | [terraform-cdp-deploy](modules/terraform-cdp-deploy/README.md) | For deployment of CDP on AWS, Azure or GCP. | | [terraform-aws-cred-permissions](modules/terraform-aws-cred-permissions/README.md) | Module for creation of the Cross Account Credential pre-requisite on AWS. Note that this module is called from the terraform-cdp-aws-prereqs module. | | [terraform-aws-permissions](modules/terraform-aws-permissions/README.md) | Module for creation of the AWS IAM permissions required by the (CDP) Public Cloud environment and datalake deployment. Note that this module is called from the terraform-cdp-aws-prereqs module. | +| [terraform-aws-ingress](modules/terraform-aws-ingress/README.md) | Module for creation and management of the Default and Knox AWS security groups for Cloudera on cloud deployments. Note that this module is called from the terraform-cdp-aws-prereqs module. | | [terraform-aws-vpc](modules/terraform-aws-vpc/README.md) | Module for creation of the VPC networking resources on AWS. Can be used to create the CDP VPC and Subnets. Note that this module is called from the terraform-cdp-aws-prereqs module. | | [terraform-aws-fw-vpc](modules/terraform-aws-fw-vpc/README.md) | Module for creation of the VPC networking resources on AWS suitable for running a Firewall in a distributed architecture on AWS. Can be used to create a networking VPC which runs the AWS Network Firewall and connects to a Cloudera on cloud full-private deployment. | | [terraform-aws-tgw](modules/terraform-aws-tgw/README.md) | Module for creation of AWS Transity Gateway (TGW) and attaching a specified list of VPCs via the TGW. This module can be used to assist in deploying Cloudera Data Platform (CDP) Public Cloud in a fully private networking configuration where a CDP VPC and Networking VPC are connected using the Transit Gateway. | diff --git a/modules/terraform-aws-ingress/.terraform-docs.yaml b/modules/terraform-aws-ingress/.terraform-docs.yaml new file mode 100644 index 0000000..0936036 --- /dev/null +++ b/modules/terraform-aws-ingress/.terraform-docs.yaml @@ -0,0 +1,21 @@ +formatter: markdown +header-from: doc_fragments/header.md +settings: + anchor: true + color: true + default: true + escape: true + html: true + indent: 2 + required: true + sensitive: true + type: true + + +sort: + enabled: true + by: required + +output: + file: README.md + mode: replace \ No newline at end of file diff --git a/modules/terraform-aws-ingress/README.md b/modules/terraform-aws-ingress/README.md new file mode 100644 index 0000000..d802790 --- /dev/null +++ b/modules/terraform-aws-ingress/README.md @@ -0,0 +1,82 @@ + +# Terraform Module for AWS Ingress (Security Groups) + +This module contains resource files and example variable definition files for creating and managing the Default and Knox AWS security groups for Cloudera on cloud deployments. + +Support for using a pre-existing Security Groups is provided via the `existing_default_security_group_name` and `existing_knox_security_group_name` input variables. When this is set no security group resources are created. Instead a lookup of the details of the existing security group takes place and the ID is returned. + +## Usage + +The [examples](./examples) directory has example of using this module: + +* `ex01-minimal_inputs` demonstrates how this module can be used to create security groups with minimum required inputs. The [terraform-aws-vpc](../../../terraform-aws-vpc/README.md) module is also used as part of this example. +* `ex02-existing_sgs` demonstrates how to use existing security groups with this module. + +The README and sample `terraform.tfvars.sample` describe how to use the example. + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | > 1.3.0 | +| [aws](#requirement\_aws) | >= 5.30 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.30 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_ec2_managed_prefix_list.cdp_prefix_list](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_managed_prefix_list) | resource | +| [aws_ec2_managed_prefix_list_entry.cdp_prefix_list_entry](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_managed_prefix_list_entry) | resource | +| [aws_security_group.cdp_default_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_security_group.cdp_knox_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_vpc_security_group_egress_rule.cdp_default_sg_egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource | +| [aws_vpc_security_group_egress_rule.cdp_knox_sg_egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.cdp_default_extra_sg_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.cdp_default_extra_sg_ingress_pl](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.cdp_default_sg_ingress_self](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.cdp_default_vpc_sg_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.cdp_knox_extra_sg_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.cdp_knox_extra_sg_ingress_pl](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.cdp_knox_sg_ingress_self](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.cdp_knox_vpc_sg_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_security_group.cdp_default_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_group) | data source | +| [aws_security_group.cdp_knox_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_group) | data source | +| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [vpc\_id](#input\_vpc\_id) | VPC ID for where the security groups will be created. | `string` | n/a | yes | +| [cdp\_default\_sg\_egress\_cidrs](#input\_cdp\_default\_sg\_egress\_cidrs) | List of egress CIDR blocks for CDP Default Security Group Egress rule | `list(string)` |
[
"0.0.0.0/0"
]
| no | +| [cdp\_knox\_sg\_egress\_cidrs](#input\_cdp\_knox\_sg\_egress\_cidrs) | List of egress CIDR blocks for CDP Knox Security Group Egress rule | `list(string)` |
[
"0.0.0.0/0"
]
| no | +| [default\_security\_group\_name](#input\_default\_security\_group\_name) | Default Security Group for Cloudera on cloud environment | `string` | `null` | no | +| [existing\_default\_security\_group\_name](#input\_existing\_default\_security\_group\_name) | Name of existing Default Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Default SG. | `string` | `null` | no | +| [existing\_knox\_security\_group\_name](#input\_existing\_knox\_security\_group\_name) | Name of existing Knox Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Knox SG. | `string` | `null` | no | +| [ingress\_extra\_cidrs\_and\_ports](#input\_ingress\_extra\_cidrs\_and\_ports) | List of extra CIDR blocks and ports to include in Security Group Ingress rules |
object({
cidrs = list(string)
ports = list(number)
})
|
{
"cidrs": [],
"ports": []
}
| no | +| [ingress\_vpc\_cidr](#input\_ingress\_vpc\_cidr) | VPC CIDR block to include in Security Group Ingress rule | `string` | `null` | no | +| [knox\_security\_group\_name](#input\_knox\_security\_group\_name) | Knox Security Group for Cloudera on cloud environment | `string` | `null` | no | +| [prefix\_list\_name](#input\_prefix\_list\_name) | Name of the AWS Prefix List to use for the security group rules. | `string` | `null` | no | +| [tags](#input\_tags) | Tags applied to provisioned resources | `map(any)` | `null` | no | +| [use\_prefix\_list\_for\_ingress](#input\_use\_prefix\_list\_for\_ingress) | Whether to use prefix lists for ingress rules instead of direct CIDR blocks | `bool` | `true` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [aws\_prefix\_list\_id](#output\_aws\_prefix\_list\_id) | AWS managed prefix list ID | +| [aws\_security\_group\_default\_arn](#output\_aws\_security\_group\_default\_arn) | AWS security group ARN for default CDP SG | +| [aws\_security\_group\_default\_id](#output\_aws\_security\_group\_default\_id) | AWS security group id for default CDP SG | +| [aws\_security\_group\_knox\_arn](#output\_aws\_security\_group\_knox\_arn) | AWS security group ARN for Knox CDP SG | +| [aws\_security\_group\_knox\_id](#output\_aws\_security\_group\_knox\_id) | AWS security group id for Knox CDP SG | + \ No newline at end of file diff --git a/modules/terraform-aws-ingress/data.tf b/modules/terraform-aws-ingress/data.tf new file mode 100644 index 0000000..dcae999 --- /dev/null +++ b/modules/terraform-aws-ingress/data.tf @@ -0,0 +1,30 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Find details of the VPC +data "aws_vpc" "vpc" { + id = var.vpc_id +} + +data "aws_security_group" "cdp_default_sg" { + + name = local.create_default_security_group ? aws_security_group.cdp_default_sg[0].name : var.existing_default_security_group_name + vpc_id = var.vpc_id +} + +data "aws_security_group" "cdp_knox_sg" { + + name = local.create_knox_security_group ? aws_security_group.cdp_knox_sg[0].name : var.existing_knox_security_group_name + vpc_id = var.vpc_id +} \ No newline at end of file diff --git a/modules/terraform-aws-ingress/defaults.tf b/modules/terraform-aws-ingress/defaults.tf new file mode 100644 index 0000000..66fb839 --- /dev/null +++ b/modules/terraform-aws-ingress/defaults.tf @@ -0,0 +1,32 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +locals { + + # ------- Determine if resources should be created ------- + create_default_security_group = (var.existing_default_security_group_name == null) + + create_knox_security_group = (var.existing_knox_security_group_name == null) + + security_group_rules_extra_ingress = flatten([ + for i, cidr in var.ingress_extra_cidrs_and_ports.cidrs : [ + for j, port in var.ingress_extra_cidrs_and_ports.ports : + { + cidr = cidr + port = port + protocol = "tcp" + }] + ]) + +} \ No newline at end of file diff --git a/modules/terraform-aws-ingress/doc_fragments/header.md b/modules/terraform-aws-ingress/doc_fragments/header.md new file mode 100644 index 0000000..ae7e645 --- /dev/null +++ b/modules/terraform-aws-ingress/doc_fragments/header.md @@ -0,0 +1,14 @@ +# Terraform Module for AWS Ingress (Security Groups) + +This module contains resource files and example variable definition files for creating and managing the Default and Knox AWS security groups for Cloudera on cloud deployments. + +Support for using a pre-existing Security Groups is provided via the `existing_default_security_group_name` and `existing_knox_security_group_name` input variables. When this is set no security group resources are created. Instead a lookup of the details of the existing security group takes place and the ID is returned. + +## Usage + +The [examples](./examples) directory has example of using this module: + +* `ex01-minimal_inputs` demonstrates how this module can be used to create security groups with minimum required inputs. The [terraform-aws-vpc](../../../terraform-aws-vpc/README.md) module is also used as part of this example. +* `ex02-existing_sgs` demonstrates how to use existing security groups with this module. + +The README and sample `terraform.tfvars.sample` describe how to use the example. diff --git a/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/main.tf b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/main.tf new file mode 100644 index 0000000..e02bff4 --- /dev/null +++ b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/main.tf @@ -0,0 +1,50 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provider "aws" { + region = var.aws_region +} + +module "ex01_vpc" { + source = "../../../terraform-aws-vpc" + + cdp_vpc = false + vpc_name = "${var.name_prefix}-vpc" + vpc_cidr = "10.11.0.0/16" + enable_nat_gateway = false + + private_cidr_range = 26 + public_cidr_range = 26 +} + +module "ex01_sg" { + source = "../.." + + vpc_id = module.ex01_vpc.vpc_id + + default_security_group_name = "${var.name_prefix}-default-sg" + knox_security_group_name = "${var.name_prefix}-knox-sg" + prefix_list_name = "${var.name_prefix}-prefix-list" + # use_prefix_list_for_ingress = false + + ingress_vpc_cidr = module.ex01_vpc.vpc_cidr_blocks[0] + + ingress_extra_cidrs_and_ports = var.ingress_extra_cidrs_and_ports + + + tags = var.tags + + depends_on = [module.ex01_vpc] + +} diff --git a/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/outputs.tf b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/outputs.tf new file mode 100644 index 0000000..e1b261d --- /dev/null +++ b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/outputs.tf @@ -0,0 +1,37 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# output "bastion_instance_public_ip" { +# value = module.ex01_bastion.bastion_instance_public_ip + +# description = "The public IP assigned to the Bastion host." +# } + +# output "bastion_instance_private_ip" { +# value = module.ex01_bastion.bastion_instance_private_ip + +# description = "The private IP assigned to the Bastion host." +# } + +# output "bastion_instance_details" { +# value = module.ex01_bastion.bastion_instance_details + +# description = "The details of the Bastion host." +# } + +# output "bastion_instance_id" { +# value = module.ex01_bastion.bastion_instance_id + +# description = "The instance ID assigned to the Bastion host." +# } \ No newline at end of file diff --git a/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample new file mode 100644 index 0000000..45c0bce --- /dev/null +++ b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample @@ -0,0 +1,30 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ------- Global Settings ------- +name_prefix = "" + +tags = { + "Project" = "terraform-cdp-modules" + "Module" = "terraform-aws-ingress" +} + +# ------- Cloud Settings ------- +aws_region = "" # Change this to specify Cloud Provider region, e.g. eu-west-1 + +# ------- Bastion settings ------- +ingress_extra_cidrs_and_ports = { + cidrs = ["/32", "/32"], + ports = [443, 22] +} diff --git a/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/variables.tf b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/variables.tf new file mode 100644 index 0000000..00b3fc5 --- /dev/null +++ b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/variables.tf @@ -0,0 +1,45 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ------- Global settings ------- +variable "name_prefix" { + type = string + description = "Shorthand name to use when naming resources." +} + +variable "tags" { + type = map(any) + description = "Tags applied to provisioned resources" + +} + +# ------- Cloud Settings ------- +variable "aws_region" { + type = string + description = "Region which Cloud resources will be created" +} + +# ------- Security Group settings ------- +variable "ingress_extra_cidrs_and_ports" { + type = object({ + cidrs = list(string) + ports = list(number) + }) + description = "List of extra CIDR blocks and ports to include in Security Group Ingress rules" + + default = { + cidrs = [], + ports = [] + } +} diff --git a/modules/terraform-aws-ingress/examples/ex02-existing_sgs/main.tf b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/main.tf new file mode 100644 index 0000000..9605964 --- /dev/null +++ b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/main.tf @@ -0,0 +1,68 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provider "aws" { + region = var.aws_region +} + +module "ex02_vpc" { + source = "../../../terraform-aws-vpc" + + cdp_vpc = false + vpc_name = "${var.name_prefix}-vpc" + vpc_cidr = "10.11.0.0/16" + enable_nat_gateway = false + + private_cidr_range = 26 + public_cidr_range = 26 +} + + +# Create security groups to pass in to module as pre-existing SGs +resource "aws_security_group" "existing_default_sg" { + vpc_id = module.ex02_vpc.vpc_id + name = "${var.name_prefix}-existing-default-sg" + description = "Default SG to simiulate existing SG" + tags = merge(var.tags, { Name = "${var.name_prefix}-existing-default-sg" }) +} + +resource "aws_security_group" "existing_knox_sg" { + vpc_id = module.ex02_vpc.vpc_id + name = "${var.name_prefix}-existing-knox-sg" + description = "Knox SG to simiulate existing SG" + tags = merge(var.tags, { Name = "${var.name_prefix}-existing-knox-sg" }) +} + +# Use existing security groups in the module +module "ex01_sg" { + source = "../.." + + vpc_id = module.ex02_vpc.vpc_id + + existing_default_security_group_name = aws_security_group.existing_default_sg.name + existing_knox_security_group_name = aws_security_group.existing_knox_sg.name + + # default_security_group_name = "${var.name_prefix}-default-sg" + # knox_security_group_name = "${var.name_prefix}-knox-sg" + # prefix_list_name = "${var.name_prefix}-prefix-list" + # # use_prefix_list_for_ingress = true + + # ingress_vpc_cidr = module.ex02_vpc.vpc_cidr_blocks[0] + # ingress_extra_cidrs_and_ports = var.ingress_extra_cidrs_and_ports + + # tags = var.tags + + depends_on = [module.ex02_vpc] + +} diff --git a/modules/terraform-aws-ingress/examples/ex02-existing_sgs/outputs.tf b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/outputs.tf new file mode 100644 index 0000000..e1b261d --- /dev/null +++ b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/outputs.tf @@ -0,0 +1,37 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# output "bastion_instance_public_ip" { +# value = module.ex01_bastion.bastion_instance_public_ip + +# description = "The public IP assigned to the Bastion host." +# } + +# output "bastion_instance_private_ip" { +# value = module.ex01_bastion.bastion_instance_private_ip + +# description = "The private IP assigned to the Bastion host." +# } + +# output "bastion_instance_details" { +# value = module.ex01_bastion.bastion_instance_details + +# description = "The details of the Bastion host." +# } + +# output "bastion_instance_id" { +# value = module.ex01_bastion.bastion_instance_id + +# description = "The instance ID assigned to the Bastion host." +# } \ No newline at end of file diff --git a/modules/terraform-aws-ingress/examples/ex02-existing_sgs/terraform.tfvars.sample b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/terraform.tfvars.sample new file mode 100644 index 0000000..45c0bce --- /dev/null +++ b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/terraform.tfvars.sample @@ -0,0 +1,30 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ------- Global Settings ------- +name_prefix = "" + +tags = { + "Project" = "terraform-cdp-modules" + "Module" = "terraform-aws-ingress" +} + +# ------- Cloud Settings ------- +aws_region = "" # Change this to specify Cloud Provider region, e.g. eu-west-1 + +# ------- Bastion settings ------- +ingress_extra_cidrs_and_ports = { + cidrs = ["/32", "/32"], + ports = [443, 22] +} diff --git a/modules/terraform-aws-ingress/examples/ex02-existing_sgs/variables.tf b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/variables.tf new file mode 100644 index 0000000..00b3fc5 --- /dev/null +++ b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/variables.tf @@ -0,0 +1,45 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ------- Global settings ------- +variable "name_prefix" { + type = string + description = "Shorthand name to use when naming resources." +} + +variable "tags" { + type = map(any) + description = "Tags applied to provisioned resources" + +} + +# ------- Cloud Settings ------- +variable "aws_region" { + type = string + description = "Region which Cloud resources will be created" +} + +# ------- Security Group settings ------- +variable "ingress_extra_cidrs_and_ports" { + type = object({ + cidrs = list(string) + ports = list(number) + }) + description = "List of extra CIDR blocks and ports to include in Security Group Ingress rules" + + default = { + cidrs = [], + ports = [] + } +} diff --git a/modules/terraform-aws-ingress/main.tf b/modules/terraform-aws-ingress/main.tf new file mode 100644 index 0000000..65c6b68 --- /dev/null +++ b/modules/terraform-aws-ingress/main.tf @@ -0,0 +1,190 @@ +# Copyright 2023 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# ------- Default Security Group ------- +resource "aws_security_group" "cdp_default_sg" { + + count = local.create_default_security_group ? 1 : 0 + + vpc_id = var.vpc_id + name = var.default_security_group_name + description = var.default_security_group_name + tags = merge(var.tags, { Name = var.default_security_group_name }) +} + +# Create self reference ingress rule to allow communication within the security group +resource "aws_vpc_security_group_ingress_rule" "cdp_default_sg_ingress_self" { + + count = local.create_default_security_group ? 1 : 0 + + security_group_id = aws_security_group.cdp_default_sg[0].id + description = "Self ingress rule for ${var.default_security_group_name}" + referenced_security_group_id = aws_security_group.cdp_default_sg[0].id + ip_protocol = "-1" + + tags = merge(var.tags, { Name = var.default_security_group_name }) +} + +# Create security group rules for VPC CIDR list +resource "aws_vpc_security_group_ingress_rule" "cdp_default_vpc_sg_ingress" { + + count = local.create_default_security_group ? 1 : 0 + + security_group_id = aws_security_group.cdp_default_sg[0].id + description = "Inter VPC CIDR ingress rule for ${var.default_security_group_name}" + cidr_ipv4 = var.ingress_vpc_cidr + ip_protocol = "-1" + + tags = merge(var.tags, { Name = var.default_security_group_name }) +} + +# Create security group rules for specified extra list of ingress rules - direct CIDR method +resource "aws_vpc_security_group_ingress_rule" "cdp_default_extra_sg_ingress" { + + count = local.create_default_security_group && !var.use_prefix_list_for_ingress ? length(local.security_group_rules_extra_ingress) : 0 + + security_group_id = aws_security_group.cdp_default_sg[0].id + description = "Extra CIDR ingress rule for ${var.default_security_group_name}" + cidr_ipv4 = tolist(local.security_group_rules_extra_ingress)[count.index].cidr + from_port = try(tolist(local.security_group_rules_extra_ingress)[count.index].port, null) + to_port = try(tolist(local.security_group_rules_extra_ingress)[count.index].port, null) + ip_protocol = tolist(local.security_group_rules_extra_ingress)[count.index].protocol + + tags = merge(var.tags, { Name = var.default_security_group_name }) +} + +# Create security group rules using prefix list method +resource "aws_vpc_security_group_ingress_rule" "cdp_default_extra_sg_ingress_pl" { + count = local.create_default_security_group && var.use_prefix_list_for_ingress ? length(var.ingress_extra_cidrs_and_ports.ports) : 0 + + security_group_id = aws_security_group.cdp_default_sg[0].id + description = "Extra CIDRs prefix list ingress rule for ${var.default_security_group_name}" + prefix_list_id = aws_ec2_managed_prefix_list.cdp_prefix_list[0].id + from_port = tolist(var.ingress_extra_cidrs_and_ports.ports)[count.index] + to_port = tolist(var.ingress_extra_cidrs_and_ports.ports)[count.index] + ip_protocol = "tcp" + tags = merge(var.tags, { Name = var.default_security_group_name }) +} + +# Terraform removes the default ALLOW ALL egress. Let's recreate this +resource "aws_vpc_security_group_egress_rule" "cdp_default_sg_egress" { + + count = local.create_default_security_group ? length(var.cdp_default_sg_egress_cidrs) : 0 + + security_group_id = aws_security_group.cdp_default_sg[0].id + description = "All traffic egress for ${var.default_security_group_name}" + ip_protocol = -1 + cidr_ipv4 = var.cdp_default_sg_egress_cidrs[count.index] #tfsec:ignore:aws-ec2-no-public-egress-sgr #tfsec:ignore:aws-vpc-no-public-egress-sgr + + tags = merge(var.tags, { Name = var.default_security_group_name }) +} + +# ------- Knox Security Groups ------- +resource "aws_security_group" "cdp_knox_sg" { + + count = local.create_knox_security_group ? 1 : 0 + + vpc_id = var.vpc_id + name = var.knox_security_group_name + description = var.knox_security_group_name + tags = merge(var.tags, { Name = var.knox_security_group_name }) +} + + +# Create self reference ingress rule to allow communication within the security group. +resource "aws_vpc_security_group_ingress_rule" "cdp_knox_sg_ingress_self" { + + count = local.create_knox_security_group ? 1 : 0 + + security_group_id = aws_security_group.cdp_knox_sg[0].id + description = "Self ingress rule for ${var.knox_security_group_name}" + referenced_security_group_id = aws_security_group.cdp_knox_sg[0].id + ip_protocol = "-1" + + tags = merge(var.tags, { Name = var.knox_security_group_name }) +} + +# Create security group rules for VPC CIDR list +resource "aws_vpc_security_group_ingress_rule" "cdp_knox_vpc_sg_ingress" { + + count = local.create_knox_security_group ? 1 : 0 + + security_group_id = aws_security_group.cdp_knox_sg[0].id + description = "Inter VPC CIDR ingress rule for ${var.knox_security_group_name}" + cidr_ipv4 = var.ingress_vpc_cidr + ip_protocol = "-1" + + tags = merge(var.tags, { Name = var.knox_security_group_name }) +} + +# Create security group rules for specified extra list of ingress rules - direct CIDR method +resource "aws_vpc_security_group_ingress_rule" "cdp_knox_extra_sg_ingress" { + + count = local.create_knox_security_group && !var.use_prefix_list_for_ingress ? length(local.security_group_rules_extra_ingress) : 0 + + security_group_id = aws_security_group.cdp_knox_sg[0].id + description = "Extra CIDR ingress rule for ${var.knox_security_group_name}" + cidr_ipv4 = tolist(local.security_group_rules_extra_ingress)[count.index].cidr + from_port = try(tolist(local.security_group_rules_extra_ingress)[count.index].port, null) + to_port = try(tolist(local.security_group_rules_extra_ingress)[count.index].port, null) + ip_protocol = tolist(local.security_group_rules_extra_ingress)[count.index].protocol + + tags = merge(var.tags, { Name = var.knox_security_group_name }) +} + +# Use existing prefix list rule for Knox with conditional +resource "aws_vpc_security_group_ingress_rule" "cdp_knox_extra_sg_ingress_pl" { + count = local.create_knox_security_group && var.use_prefix_list_for_ingress ? length(var.ingress_extra_cidrs_and_ports.ports) : 0 + + security_group_id = aws_security_group.cdp_knox_sg[0].id + description = "Extra CIDRs prefix list ingress rule for ${var.knox_security_group_name}" + prefix_list_id = aws_ec2_managed_prefix_list.cdp_prefix_list[0].id + from_port = tolist(var.ingress_extra_cidrs_and_ports.ports)[count.index] + to_port = tolist(var.ingress_extra_cidrs_and_ports.ports)[count.index] + ip_protocol = "tcp" + tags = merge(var.tags, { Name = var.knox_security_group_name }) +} + +# Terraform removes the default ALLOW ALL egress. Let's recreate this +resource "aws_vpc_security_group_egress_rule" "cdp_knox_sg_egress" { + + count = local.create_knox_security_group ? length(var.cdp_knox_sg_egress_cidrs) : 0 + + security_group_id = aws_security_group.cdp_knox_sg[0].id + description = "All traffic egress for ${var.knox_security_group_name}" + ip_protocol = -1 + cidr_ipv4 = var.cdp_knox_sg_egress_cidrs[count.index] #tfsec:ignore:aws-ec2-no-public-egress-sgr #tfsec:ignore:aws-vpc-no-public-egress-sgr + + tags = merge(var.tags, { Name = var.knox_security_group_name }) +} + + +# Create prefix list for extra ingress rules if specified and prefix list option is enabled +resource "aws_ec2_managed_prefix_list" "cdp_prefix_list" { + count = var.use_prefix_list_for_ingress ? 1 : 0 + + name = var.prefix_list_name + address_family = "IPv4" + max_entries = length(var.ingress_extra_cidrs_and_ports.cidrs) +} + +resource "aws_ec2_managed_prefix_list_entry" "cdp_prefix_list_entry" { + for_each = var.use_prefix_list_for_ingress ? { for idx, cidr in var.ingress_extra_cidrs_and_ports.cidrs : idx => cidr } : {} + + prefix_list_id = aws_ec2_managed_prefix_list.cdp_prefix_list[0].id + cidr = each.value + description = "${var.prefix_list_name}-ingress" + +} diff --git a/modules/terraform-aws-ingress/outputs.tf b/modules/terraform-aws-ingress/outputs.tf new file mode 100644 index 0000000..790a119 --- /dev/null +++ b/modules/terraform-aws-ingress/outputs.tf @@ -0,0 +1,44 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +output "aws_security_group_default_id" { + value = data.aws_security_group.cdp_default_sg.id + + description = "AWS security group id for default CDP SG" +} + +output "aws_security_group_default_arn" { + value = data.aws_security_group.cdp_default_sg.arn + + description = "AWS security group ARN for default CDP SG" +} + +output "aws_security_group_knox_id" { + value = data.aws_security_group.cdp_knox_sg.id + + description = "AWS security group id for Knox CDP SG" +} + + +output "aws_security_group_knox_arn" { + value = data.aws_security_group.cdp_knox_sg.arn + + description = "AWS security group ARN for Knox CDP SG" +} + +output "aws_prefix_list_id" { + value = var.use_prefix_list_for_ingress ? aws_ec2_managed_prefix_list.cdp_prefix_list[0].id : null + + description = "AWS managed prefix list ID" +} diff --git a/modules/terraform-aws-ingress/provider.tf b/modules/terraform-aws-ingress/provider.tf new file mode 100644 index 0000000..f7b8d73 --- /dev/null +++ b/modules/terraform-aws-ingress/provider.tf @@ -0,0 +1,24 @@ +# Copyright 2023 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.30" + } + } + + required_version = "> 1.3.0" +} diff --git a/modules/terraform-aws-ingress/variables.tf b/modules/terraform-aws-ingress/variables.tf new file mode 100644 index 0000000..5554a1d --- /dev/null +++ b/modules/terraform-aws-ingress/variables.tf @@ -0,0 +1,127 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +variable "default_security_group_name" { + type = string + + description = "Default Security Group for Cloudera on cloud environment" + + default = null + + validation { + condition = (var.default_security_group_name == null ? true : length(var.default_security_group_name) <= 256) + error_message = "The length of default_security_group_name must be 256 characters or less." + } +} + +variable "knox_security_group_name" { + type = string + + description = "Knox Security Group for Cloudera on cloud environment" + + default = null + + validation { + condition = (var.knox_security_group_name == null ? true : length(var.knox_security_group_name) <= 256) + error_message = "The length of knox_security_group_name must be 256 characters or less." + } +} + +variable "ingress_extra_cidrs_and_ports" { + type = object({ + cidrs = list(string) + ports = list(number) + }) + description = "List of extra CIDR blocks and ports to include in Security Group Ingress rules" + + default = { + cidrs = [], + ports = [] + } +} + +variable "ingress_vpc_cidr" { + type = string + + description = "VPC CIDR block to include in Security Group Ingress rule" + + default = null + + validation { + condition = (var.ingress_vpc_cidr != null) || (var.existing_knox_security_group_name != null && var.existing_default_security_group_name != null) + error_message = "The ingress_vpc_cidr variable is required when creating new security groups (when existing_knox_security_group_name or existing_default_security_group_name is null)." + } +} + +variable "cdp_default_sg_egress_cidrs" { + type = list(string) + + description = "List of egress CIDR blocks for CDP Default Security Group Egress rule" + + default = ["0.0.0.0/0"] +} + +variable "cdp_knox_sg_egress_cidrs" { + type = list(string) + + description = "List of egress CIDR blocks for CDP Knox Security Group Egress rule" + + default = ["0.0.0.0/0"] +} + +variable "vpc_id" { + type = string + description = "VPC ID for where the security groups will be created." +} + +variable "use_prefix_list_for_ingress" { + description = "Whether to use prefix lists for ingress rules instead of direct CIDR blocks" + type = bool + + default = true +} + +variable "prefix_list_name" { + type = string + description = "Name of the AWS Prefix List to use for the security group rules." + + default = null + + validation { + condition = !var.use_prefix_list_for_ingress || (var.use_prefix_list_for_ingress && var.prefix_list_name != null) + error_message = "When use_prefix_list_for_ingress is set to true, prefix_list_name must not be null." + } +} + +variable "tags" { + type = map(any) + description = "Tags applied to provisioned resources" + + default = null +} + +# ------- Support for existing Security Groups ------- +variable "existing_default_security_group_name" { + type = string + description = "Name of existing Default Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Default SG." + + default = null +} + +variable "existing_knox_security_group_name" { + type = string + description = "Name of existing Knox Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Knox SG." + + default = null +} diff --git a/modules/terraform-cdp-aws-pre-reqs/README.md b/modules/terraform-cdp-aws-pre-reqs/README.md index 23fa7e4..4e0e3e9 100644 --- a/modules/terraform-cdp-aws-pre-reqs/README.md +++ b/modules/terraform-cdp-aws-pre-reqs/README.md @@ -36,6 +36,7 @@ In each directory an example `terraform.tfvars.sample` values file is included t | Name | Source | Version | |------|--------|---------| | [aws\_cdp\_cred\_permissions](#module\_aws\_cdp\_cred\_permissions) | ../terraform-aws-cred-permissions | n/a | +| [aws\_cdp\_ingress](#module\_aws\_cdp\_ingress) | ../terraform-aws-ingress | n/a | | [aws\_cdp\_permissions](#module\_aws\_cdp\_permissions) | ../terraform-aws-permissions | n/a | | [aws\_cdp\_vpc](#module\_aws\_cdp\_vpc) | ../terraform-aws-vpc | n/a | @@ -51,18 +52,10 @@ In each directory an example `terraform.tfvars.sample` values file is included t | [aws_s3_bucket_versioning.cdp_storage_location_versioning](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource | | [aws_s3_object.cdp_backup_storage_object](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | | [aws_s3_object.cdp_log_storage_object](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | -| [aws_security_group.cdp_default_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | | [aws_security_group.cdp_endpoint_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | -| [aws_security_group.cdp_knox_sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | -| [aws_security_group_rule.cdp_default_sg_egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.cdp_default_sg_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.cdp_default_sg_ingress_self](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | | [aws_security_group_rule.cdp_endpoint_ingress_self](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | | [aws_security_group_rule.cdp_endpoint_sg_egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | | [aws_security_group_rule.cdp_endpoint_sg_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.cdp_knox_sg_egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.cdp_knox_sg_ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.cdp_knox_sg_ingress_self](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | | [aws_vpc_endpoint.gateway_endpoints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_endpoint) | resource | | [aws_vpc_endpoint.interface_endpoints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_endpoint) | resource | | [random_id.bucket_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | @@ -108,6 +101,8 @@ In each directory an example `terraform.tfvars.sample` values file is included t | [enable\_bucket\_versioning](#input\_enable\_bucket\_versioning) | Flag to enable versioning of S3 buckets. | `bool` | `true` | no | | [enable\_kms\_bucket\_encryption](#input\_enable\_kms\_bucket\_encryption) | Flag to create AWS KMS for encryption of S3 buckets. Currently disabled as further settings needed for successful CDP deployment. | `bool` | `false` | no | | [env\_tags](#input\_env\_tags) | Tags applied to provised resources | `map(any)` | `null` | no | +| [existing\_default\_security\_group\_name](#input\_existing\_default\_security\_group\_name) | Name of existing Default Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Default SG. | `string` | `null` | no | +| [existing\_knox\_security\_group\_name](#input\_existing\_knox\_security\_group\_name) | Name of existing Knox Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Knox SG. | `string` | `null` | no | | [existing\_xaccount\_role\_name](#input\_existing\_xaccount\_role\_name) | Name of existing CDP Cross Account Role. If set then no Cross Account policy or role resources are created. | `string` | `null` | no | | [idbroker\_policy\_name](#input\_idbroker\_policy\_name) | IDBroker Policy name | `string` | `null` | no | | [idbroker\_role\_name](#input\_idbroker\_role\_name) | IDBroker service role Name | `string` | `null` | no | @@ -116,6 +111,7 @@ In each directory an example `terraform.tfvars.sample` values file is included t | [log\_data\_access\_policy\_name](#input\_log\_data\_access\_policy\_name) | Log Data Access Policy Name | `string` | `null` | no | | [log\_role\_name](#input\_log\_role\_name) | Log service role Name | `string` | `null` | no | | [log\_storage](#input\_log\_storage) | Optional log locations for CDP environment. If not provided follow the data\_storage variable |
object({
log_storage_bucket = string
log_storage_object = string
})
| `null` | no | +| [prefix\_list\_name](#input\_prefix\_list\_name) | Prefix List for Security Group Ingress rules | `string` | `null` | no | | [private\_cidr\_range](#input\_private\_cidr\_range) | Size of each private subnet. Required if create\_vpc is true. Number of subnets will be automatically selected to match on the number of Availability Zones in the selected AWS region. (Depending on the selected deployment pattern, one subnet will be created per region.) | `number` | `19` | no | | [private\_network\_extensions](#input\_private\_network\_extensions) | Enable creation of resources for connectivity to CDP Control Plane (public subnet and NAT Gateway) for Private Deployment. Only relevant for private deployment template | `bool` | `true` | no | | [public\_cidr\_range](#input\_public\_cidr\_range) | Size of each public subnet. Required if create\_vpc is true. Number of subnets will be automatically selected to match on the number of Availability Zones in the selected AWS region. (Depending on the selected deployment pattern, one subnet will be created per region.) | `number` | `24` | no | diff --git a/modules/terraform-cdp-aws-pre-reqs/defaults.tf b/modules/terraform-cdp-aws-pre-reqs/defaults.tf index 17f5440..4c7c06e 100644 --- a/modules/terraform-cdp-aws-pre-reqs/defaults.tf +++ b/modules/terraform-cdp-aws-pre-reqs/defaults.tf @@ -24,12 +24,12 @@ locals { vpc_name = coalesce(var.vpc_name, "${var.env_prefix}-net") # Security Groups - security_group_default_name = coalesce(var.security_group_default_name, "${var.env_prefix}-default-sg") - - security_group_knox_name = coalesce(var.security_group_knox_name, "${var.env_prefix}-knox-sg") - + security_group_default_name = coalesce(var.security_group_default_name, "${var.env_prefix}-default-sg") + security_group_knox_name = coalesce(var.security_group_knox_name, "${var.env_prefix}-knox-sg") security_group_endpoint_name = coalesce(var.security_group_endpoint_name, "${var.env_prefix}-endpoint-sg") + prefix_list_name = coalesce(var.prefix_list_name, "${var.env_prefix}-prefix-list") + security_group_rules_ingress = [ { # CIDR ingress diff --git a/modules/terraform-cdp-aws-pre-reqs/main.tf b/modules/terraform-cdp-aws-pre-reqs/main.tf index 4e841c0..0b604ac 100644 --- a/modules/terraform-cdp-aws-pre-reqs/main.tf +++ b/modules/terraform-cdp-aws-pre-reqs/main.tf @@ -43,92 +43,23 @@ module "aws_cdp_vpc" { } # ------- Security Groups ------- -# Default SG -resource "aws_security_group" "cdp_default_sg" { - vpc_id = module.aws_cdp_vpc.vpc_id - name = local.security_group_default_name - description = local.security_group_default_name - tags = merge(local.env_tags, { Name = local.security_group_default_name }) -} -# Create self reference ingress rule to allow communication within the security group -resource "aws_security_group_rule" "cdp_default_sg_ingress_self" { - security_group_id = aws_security_group.cdp_default_sg.id - type = "ingress" - from_port = 0 - to_port = 0 - description = "Self-reference ingress rule" - protocol = "all" - self = true -} +# Default and Knox SG +module "aws_cdp_ingress" { -# Create security group rules from combining the default and extra list of ingress rules -resource "aws_security_group_rule" "cdp_default_sg_ingress" { - count = length(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress)) + source = "../terraform-aws-ingress" - description = "Ingress rules for Default CDP Security Group" - security_group_id = aws_security_group.cdp_default_sg.id - type = "ingress" - cidr_blocks = tolist(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress))[count.index].cidr - from_port = tolist(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress))[count.index].port - to_port = tolist(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress))[count.index].port - protocol = tolist(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress))[count.index].protocol -} + vpc_id = module.aws_cdp_vpc.vpc_id -# Terraform removes the default ALLOW ALL egress. Let's recreate this -resource "aws_security_group_rule" "cdp_default_sg_egress" { + default_security_group_name = local.security_group_default_name + knox_security_group_name = local.security_group_knox_name + prefix_list_name = local.prefix_list_name - description = "Egress rule for Default CDP Security Group" - security_group_id = aws_security_group.cdp_default_sg.id - type = "egress" - cidr_blocks = var.cdp_default_sg_egress_cidrs #tfsec:ignore:aws-ec2-no-public-egress-sgr #tfsec:ignore:aws-vpc-no-public-egress-sgr - from_port = 0 - to_port = 0 - protocol = "all" -} + ingress_vpc_cidr = module.aws_cdp_vpc.vpc_cidr_blocks[0] + ingress_extra_cidrs_and_ports = var.ingress_extra_cidrs_and_ports -# Knox SG -resource "aws_security_group" "cdp_knox_sg" { - vpc_id = module.aws_cdp_vpc.vpc_id - name = local.security_group_knox_name - description = local.security_group_knox_name - tags = merge(local.env_tags, { Name = local.security_group_knox_name }) -} - -# Create self reference ingress rule to allow communication within the security group. -resource "aws_security_group_rule" "cdp_knox_sg_ingress_self" { - security_group_id = aws_security_group.cdp_knox_sg.id - type = "ingress" - from_port = 0 - to_port = 0 - description = "Self-reference ingress rule" - protocol = "all" - self = true -} - -# Create security group rules from combining the default and extra list of ingress rules -resource "aws_security_group_rule" "cdp_knox_sg_ingress" { - count = length(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress)) - - description = "Ingress rule for Knox CDP Security Group" - security_group_id = aws_security_group.cdp_knox_sg.id - type = "ingress" - cidr_blocks = tolist(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress))[count.index].cidr - from_port = tolist(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress))[count.index].port - to_port = tolist(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress))[count.index].port - protocol = tolist(concat(local.security_group_rules_ingress, local.security_group_rules_extra_ingress))[count.index].protocol -} - -# Terraform removes the default ALLOW ALL egress. Let's recreate this -resource "aws_security_group_rule" "cdp_knox_sg_egress" { + tags = local.env_tags - description = "Egress rule for Knox CDP Security Group" - security_group_id = aws_security_group.cdp_knox_sg.id - type = "egress" - cidr_blocks = var.cdp_knox_sg_egress_cidrs #tfsec:ignore:aws-ec2-no-public-egress-sgr #tfsec:ignore:aws-vpc-no-public-egress-sgr - from_port = 0 - to_port = 0 - protocol = "all" } # VPC Endpoint SG diff --git a/modules/terraform-cdp-aws-pre-reqs/outputs.tf b/modules/terraform-cdp-aws-pre-reqs/outputs.tf index e30c7cf..e4d3005 100644 --- a/modules/terraform-cdp-aws-pre-reqs/outputs.tf +++ b/modules/terraform-cdp-aws-pre-reqs/outputs.tf @@ -122,13 +122,13 @@ output "aws_backup_storage_location" { } output "aws_security_group_default_id" { - value = aws_security_group.cdp_default_sg.id + value = module.aws_cdp_ingress.aws_security_group_default_id description = "AWS security group id for default CDP SG" } output "aws_security_group_knox_id" { - value = aws_security_group.cdp_knox_sg.id + value = module.aws_cdp_ingress.aws_security_group_knox_id description = "AWS security group id for Knox CDP SG" } diff --git a/modules/terraform-cdp-aws-pre-reqs/variables.tf b/modules/terraform-cdp-aws-pre-reqs/variables.tf index cc92561..30079cc 100644 --- a/modules/terraform-cdp-aws-pre-reqs/variables.tf +++ b/modules/terraform-cdp-aws-pre-reqs/variables.tf @@ -233,6 +233,19 @@ variable "security_group_knox_name" { } } +variable "prefix_list_name" { + type = string + + description = "Prefix List for Security Group Ingress rules" + + default = null + + validation { + condition = (var.prefix_list_name == null ? true : length(var.prefix_list_name) <= 256) + error_message = "The length of prefix_list_name must be 256 characters or less." + } +} + variable "security_group_endpoint_name" { type = string @@ -687,10 +700,25 @@ variable "ranger_audit_role_name" { } } -# ------- Support for pre-existing roles ------- +# ------- Support for pre-existing resources ------- variable "existing_xaccount_role_name" { type = string description = "Name of existing CDP Cross Account Role. If set then no Cross Account policy or role resources are created." default = null } + +variable "existing_default_security_group_name" { + type = string + description = "Name of existing Default Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Default SG." + + default = null +} + +variable "existing_knox_security_group_name" { + type = string + description = "Name of existing Knox Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Knox SG." + + default = null +} + From 2431c93603a5bfe1872d6085792c0097893e9ece Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 12 Sep 2025 20:05:00 +0100 Subject: [PATCH 2/2] Add terraform-azure-ingress module Signed-off-by: Jim Enright --- README.md | 1 + .../terraform.tfvars.sample | 2 +- .../examples/ex02-existing_sgs/main.tf | 10 -- .../.terraform-docs.yaml | 21 +++ modules/terraform-azure-ingress/README.md | 70 +++++++++ modules/terraform-azure-ingress/data.tf | 23 +++ modules/terraform-azure-ingress/defaults.tf | 22 +++ .../doc_fragments/header.md | 14 ++ .../examples/ex01-minimal_inputs/main.tf | 109 ++++++++++++++ .../examples/ex01-minimal_inputs/outputs.tf | 25 +++ .../terraform.tfvars.sample | 33 ++++ .../examples/ex01-minimal_inputs/variables.tf | 45 ++++++ .../examples/ex02-existing_sgs/main.tf | 81 ++++++++++ .../examples/ex02-existing_sgs/outputs.tf | 25 +++ .../ex02-existing_sgs/terraform.tfvars.sample | 27 ++++ .../examples/ex02-existing_sgs/variables.tf | 45 ++++++ modules/terraform-azure-ingress/main.tf | 75 +++++++++ modules/terraform-azure-ingress/outputs.tf | 25 +++ modules/terraform-azure-ingress/provider.tf | 25 +++ modules/terraform-azure-ingress/variables.tf | 142 ++++++++++++++++++ .../terraform-cdp-azure-pre-reqs/README.md | 5 +- modules/terraform-cdp-azure-pre-reqs/main.tf | 53 +------ .../terraform-cdp-azure-pre-reqs/outputs.tf | 4 +- 23 files changed, 820 insertions(+), 62 deletions(-) create mode 100644 modules/terraform-azure-ingress/.terraform-docs.yaml create mode 100644 modules/terraform-azure-ingress/README.md create mode 100644 modules/terraform-azure-ingress/data.tf create mode 100644 modules/terraform-azure-ingress/defaults.tf create mode 100644 modules/terraform-azure-ingress/doc_fragments/header.md create mode 100644 modules/terraform-azure-ingress/examples/ex01-minimal_inputs/main.tf create mode 100644 modules/terraform-azure-ingress/examples/ex01-minimal_inputs/outputs.tf create mode 100644 modules/terraform-azure-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample create mode 100644 modules/terraform-azure-ingress/examples/ex01-minimal_inputs/variables.tf create mode 100644 modules/terraform-azure-ingress/examples/ex02-existing_sgs/main.tf create mode 100644 modules/terraform-azure-ingress/examples/ex02-existing_sgs/outputs.tf create mode 100644 modules/terraform-azure-ingress/examples/ex02-existing_sgs/terraform.tfvars.sample create mode 100644 modules/terraform-azure-ingress/examples/ex02-existing_sgs/variables.tf create mode 100644 modules/terraform-azure-ingress/main.tf create mode 100644 modules/terraform-azure-ingress/outputs.tf create mode 100644 modules/terraform-azure-ingress/provider.tf create mode 100644 modules/terraform-azure-ingress/variables.tf diff --git a/README.md b/README.md index b63c8d4..ff03d47 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ This repository contains a number of Terraform modules for creation of the pre-r | [terraform-aws-permissions](modules/terraform-aws-permissions/README.md) | Module for creation of the AWS IAM permissions required by the (CDP) Public Cloud environment and datalake deployment. Note that this module is called from the terraform-cdp-aws-prereqs module. | | [terraform-aws-firewall](modules/terraform-aws-firewall/README.md) | Module to create and configure to create and configure an AWS Network Firewall. This module can be used to assist in deploying Cloudera Data Platform (CDP) Public Cloud in a fully private networking configuration where the CDP Environment is connected to a Networking VPC running the Firewall. | | [terraform-azure-resource-group](modules/terraform-azure-resource-group/README.md) | Module for creation of a Resource Group on Azure. Can be used for creation of the pre-requisite resource group for Cloudera Data Platform (CDP) Public Cloud. | +| [terraform-azure-ingress](modules/terraform-azure-ingress/README.md) | Module for creation and management of the Default and Knox Azure network security groups for Cloudera on cloud deployments. Note that this module is called from the terraform-cdp-azure-prereqs module. | | [terraform-azure-vnet](modules/terraform-azure-vnet/README.md) | Module for creation of the Virtual Network (VNET) on Azure. Can be used for creation of the pre-requisite VNet and subnets for Cloudera Data Platform (CDP) Public Cloud. | | [terraform-azure-cred-permissions](modules/terraform-azure-cred-permissions/README.md) | Module for creation of the Cross Account Credential pre-requisites on Azure. Note that this module is called from the terraform-cdp-azure-prereqs module. | | [terraform-azure-bastion](modules/terraform-azure-bastion/README.md) | Module to create a Bastion Virtual Machine instance on Azure. | diff --git a/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample index 45c0bce..b00ad4e 100644 --- a/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample +++ b/modules/terraform-aws-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample @@ -23,7 +23,7 @@ tags = { # ------- Cloud Settings ------- aws_region = "" # Change this to specify Cloud Provider region, e.g. eu-west-1 -# ------- Bastion settings ------- +# ------- Ingress settings ------- ingress_extra_cidrs_and_ports = { cidrs = ["/32", "/32"], ports = [443, 22] diff --git a/modules/terraform-aws-ingress/examples/ex02-existing_sgs/main.tf b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/main.tf index 9605964..ea5bc6e 100644 --- a/modules/terraform-aws-ingress/examples/ex02-existing_sgs/main.tf +++ b/modules/terraform-aws-ingress/examples/ex02-existing_sgs/main.tf @@ -53,16 +53,6 @@ module "ex01_sg" { existing_default_security_group_name = aws_security_group.existing_default_sg.name existing_knox_security_group_name = aws_security_group.existing_knox_sg.name - # default_security_group_name = "${var.name_prefix}-default-sg" - # knox_security_group_name = "${var.name_prefix}-knox-sg" - # prefix_list_name = "${var.name_prefix}-prefix-list" - # # use_prefix_list_for_ingress = true - - # ingress_vpc_cidr = module.ex02_vpc.vpc_cidr_blocks[0] - # ingress_extra_cidrs_and_ports = var.ingress_extra_cidrs_and_ports - - # tags = var.tags - depends_on = [module.ex02_vpc] } diff --git a/modules/terraform-azure-ingress/.terraform-docs.yaml b/modules/terraform-azure-ingress/.terraform-docs.yaml new file mode 100644 index 0000000..0936036 --- /dev/null +++ b/modules/terraform-azure-ingress/.terraform-docs.yaml @@ -0,0 +1,21 @@ +formatter: markdown +header-from: doc_fragments/header.md +settings: + anchor: true + color: true + default: true + escape: true + html: true + indent: 2 + required: true + sensitive: true + type: true + + +sort: + enabled: true + by: required + +output: + file: README.md + mode: replace \ No newline at end of file diff --git a/modules/terraform-azure-ingress/README.md b/modules/terraform-azure-ingress/README.md new file mode 100644 index 0000000..7a0d7e0 --- /dev/null +++ b/modules/terraform-azure-ingress/README.md @@ -0,0 +1,70 @@ + +# Terraform Module for Azure Ingress (Security Groups) + +This module contains resource files and example variable definition files for creating and managing the Default and Knox Azure network security groups for Cloudera on cloud deployments. + +Support for using a pre-existing Security Groups is provided via the `existing_default_security_group_name` and `existing_knox_security_group_name` input variables. When this is set no security group resources are created. Instead a lookup of the details of the existing security group takes place and the ID is returned. + +## Usage + +The [examples](./examples) directory has example Azure Cloud Service Provider deployments for different scenarios: + +* `ex01-minimal_inputs` demonstrates how this module can be used to create security groups with minimum required inputs. +* `ex02-existing_sgs` demonstrates how to use existing security groups with this module. + +The README and sample `terraform.tfvars.sample` describe how to use the example. + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.9.0 | +| [azurerm](#requirement\_azurerm) | >= 4.0.0 | + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | >= 4.0.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [azurerm_network_security_group.cdp_default_sg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group) | resource | +| [azurerm_network_security_group.cdp_knox_sg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group) | resource | +| [azurerm_network_security_rule.cdp_default_sg_ingress_extra_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_rule) | resource | +| [azurerm_network_security_rule.cdp_knox_sg_ingress_extra_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_rule) | resource | +| [azurerm_network_security_group.cdp_default_sg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/network_security_group) | data source | +| [azurerm_network_security_group.cdp_knox_sg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/network_security_group) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [azure\_region](#input\_azure\_region) | Region which Cloud resources will be created | `string` | n/a | yes | +| [resource\_group\_name](#input\_resource\_group\_name) | Azrue Resource Group for Managed Identities. | `string` | n/a | yes | +| [default\_security\_group\_ingress\_destination\_address\_prefix](#input\_default\_security\_group\_ingress\_destination\_address\_prefix) | Destination address prefix for Default Security Group Ingress rules | `string` | `"*"` | no | +| [default\_security\_group\_ingress\_priority](#input\_default\_security\_group\_ingress\_priority) | Priority for Default Security Group Ingress rules | `number` | `201` | no | +| [default\_security\_group\_ingress\_protocol](#input\_default\_security\_group\_ingress\_protocol) | Protocol for Default Security Group Ingress rules | `string` | `"Tcp"` | no | +| [default\_security\_group\_name](#input\_default\_security\_group\_name) | Default Security Group for Cloudera on cloud environment | `string` | `null` | no | +| [existing\_default\_security\_group\_name](#input\_existing\_default\_security\_group\_name) | Name of existing Default Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Default SG. | `string` | `null` | no | +| [existing\_knox\_security\_group\_name](#input\_existing\_knox\_security\_group\_name) | Name of existing Knox Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Knox SG. | `string` | `null` | no | +| [ingress\_extra\_cidrs\_and\_ports](#input\_ingress\_extra\_cidrs\_and\_ports) | List of extra CIDR blocks and ports to include in Security Group Ingress rules |
object({
cidrs = list(string)
ports = list(number)
})
|
{
"cidrs": [],
"ports": []
}
| no | +| [knox\_security\_group\_ingress\_destination\_address\_prefix](#input\_knox\_security\_group\_ingress\_destination\_address\_prefix) | Destination address prefix for Knox Security Group Ingress rules | `string` | `"*"` | no | +| [knox\_security\_group\_ingress\_priority](#input\_knox\_security\_group\_ingress\_priority) | Priority for Knox Security Group Ingress rules | `number` | `201` | no | +| [knox\_security\_group\_ingress\_protocol](#input\_knox\_security\_group\_ingress\_protocol) | Protocol for Knox Security Group Ingress rules | `string` | `"Tcp"` | no | +| [knox\_security\_group\_name](#input\_knox\_security\_group\_name) | Knox Security Group for CCloudera on cloud environment | `string` | `null` | no | +| [tags](#input\_tags) | Tags applied to provised resources | `map(any)` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [azure\_default\_security\_group\_uri](#output\_azure\_default\_security\_group\_uri) | Azure Default Security Group URI | +| [azure\_knox\_security\_group\_uri](#output\_azure\_knox\_security\_group\_uri) | Azure Knox Security Group URI | + \ No newline at end of file diff --git a/modules/terraform-azure-ingress/data.tf b/modules/terraform-azure-ingress/data.tf new file mode 100644 index 0000000..5f8c434 --- /dev/null +++ b/modules/terraform-azure-ingress/data.tf @@ -0,0 +1,23 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +data "azurerm_network_security_group" "cdp_default_sg" { + name = local.create_default_security_group ? azurerm_network_security_group.cdp_default_sg[0].name : var.existing_default_security_group_name + resource_group_name = var.resource_group_name +} + +data "azurerm_network_security_group" "cdp_knox_sg" { + name = local.create_knox_security_group ? azurerm_network_security_group.cdp_knox_sg[0].name : var.existing_knox_security_group_name + resource_group_name = var.resource_group_name +} diff --git a/modules/terraform-azure-ingress/defaults.tf b/modules/terraform-azure-ingress/defaults.tf new file mode 100644 index 0000000..c0236d7 --- /dev/null +++ b/modules/terraform-azure-ingress/defaults.tf @@ -0,0 +1,22 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +locals { + + # ------- Determine if resources should be created ------- + create_default_security_group = (var.existing_default_security_group_name == null) + + create_knox_security_group = (var.existing_knox_security_group_name == null) + +} \ No newline at end of file diff --git a/modules/terraform-azure-ingress/doc_fragments/header.md b/modules/terraform-azure-ingress/doc_fragments/header.md new file mode 100644 index 0000000..4572ce9 --- /dev/null +++ b/modules/terraform-azure-ingress/doc_fragments/header.md @@ -0,0 +1,14 @@ +# Terraform Module for Azure Ingress (Security Groups) + +This module contains resource files and example variable definition files for creating and managing the Default and Knox Azure network security groups for Cloudera on cloud deployments. + +Support for using a pre-existing Security Groups is provided via the `existing_default_security_group_name` and `existing_knox_security_group_name` input variables. When this is set no security group resources are created. Instead a lookup of the details of the existing security group takes place and the ID is returned. + +## Usage + +The [examples](./examples) directory has example Azure Cloud Service Provider deployments for different scenarios: + +* `ex01-minimal_inputs` demonstrates how this module can be used to create security groups with minimum required inputs. +* `ex02-existing_sgs` demonstrates how to use existing security groups with this module. + +The README and sample `terraform.tfvars.sample` describe how to use the example. diff --git a/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/main.tf b/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/main.tf new file mode 100644 index 0000000..5efcb43 --- /dev/null +++ b/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/main.tf @@ -0,0 +1,109 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_version = ">= 1.5.7" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 4.0.0" + } + } +} + +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } + +} + +# ------- Azure Resource Group ------- +module "rmgp" { + source = "../../../terraform-azure-resource-group" + + resourcegroup_name = "${var.env_prefix}-rg" + azure_region = var.azure_region + + tags = merge(var.env_tags, { Name = "${var.env_prefix}-rg" }) +} + +# ------- Azure SGs ------- +module "ex01_sg" { + source = "../.." + + resource_group_name = module.rmgp.resource_group_name + azure_region = var.azure_region + + default_security_group_name = "${var.env_prefix}-default-sg" + knox_security_group_name = "${var.env_prefix}-knox-sg" + + ingress_extra_cidrs_and_ports = var.ingress_extra_cidrs_and_ports + + tags = var.env_tags + + depends_on = [module.rmgp] +} + +# deployment_template = var.deployment_template +# resourcegroup_name = module.rmgp.resource_group_name +# vnet_name = "${var.env_prefix}-net" +# vnet_cidr = var.vnet_cidr +# vnet_region = var.azure_region + +# cdp_subnet_prefix = "${var.env_prefix}-cdp-sbnt" +# gateway_subnet_prefix = "${var.env_prefix}-gw-sbnt" +# delegated_subnet_prefix = "${var.env_prefix}-delegated-sbnt" + +# subnet_count = var.subnet_count +# cdp_subnet_range = var.cdp_subnet_range +# cdp_subnets_private_endpoint_network_policies = var.cdp_subnets_private_endpoint_network_policies + +# gateway_subnet_range = var.gateway_subnet_range +# gateway_subnets_private_endpoint_network_policies = var.gateway_subnets_private_endpoint_network_policies +# delegated_subnet_range = var.delegated_subnet_range + +# tags = var.env_tags + +# depends_on = [module.rmgp] +# } + + +# module "ex01_cdp_vnet" { +# source = "../.." + +# deployment_template = var.deployment_template +# resourcegroup_name = module.rmgp.resource_group_name +# vnet_name = "${var.env_prefix}-net" +# vnet_cidr = var.vnet_cidr +# vnet_region = var.azure_region + +# cdp_subnet_prefix = "${var.env_prefix}-cdp-sbnt" +# gateway_subnet_prefix = "${var.env_prefix}-gw-sbnt" +# delegated_subnet_prefix = "${var.env_prefix}-delegated-sbnt" + +# subnet_count = var.subnet_count +# cdp_subnet_range = var.cdp_subnet_range +# cdp_subnets_private_endpoint_network_policies = var.cdp_subnets_private_endpoint_network_policies + +# gateway_subnet_range = var.gateway_subnet_range +# gateway_subnets_private_endpoint_network_policies = var.gateway_subnets_private_endpoint_network_policies +# delegated_subnet_range = var.delegated_subnet_range + +# tags = var.env_tags + +# depends_on = [module.rmgp] +# } diff --git a/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/outputs.tf b/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/outputs.tf new file mode 100644 index 0000000..cc870d6 --- /dev/null +++ b/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/outputs.tf @@ -0,0 +1,25 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +output "azure_security_group_default_uri" { + value = module.ex01_sg.azure_default_security_group_uri + + description = "Azure Default Security Group URI" +} + +output "azure_knox_security_group_uri" { + value = module.ex01_sg.azure_knox_security_group_uri + + description = "Azure Knox Security Group URI" +} diff --git a/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample b/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample new file mode 100644 index 0000000..669ea67 --- /dev/null +++ b/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/terraform.tfvars.sample @@ -0,0 +1,33 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ------- Global settings ------- +env_prefix = "" # Required name prefix for cloud and CDP resources, e.g. cldr1 + +# ------- Cloud Settings ------- +azure_region = "" # Change this to specify Cloud Provider region, e.g. eastus + +# ------- Resource Tagging ------- +# **NOTE: An example of how to specify tags is below; uncomment & edit if required +# env_tags = { +# owner = "" +# project = "" +# enddate = "" +# } + +# ------- Ingress settings ------- +ingress_extra_cidrs_and_ports = { + cidrs = ["/32", "/32"], + ports = [443, 22] +} diff --git a/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/variables.tf b/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/variables.tf new file mode 100644 index 0000000..bd02be5 --- /dev/null +++ b/modules/terraform-azure-ingress/examples/ex01-minimal_inputs/variables.tf @@ -0,0 +1,45 @@ +# Copyright 2023 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ------- Global settings ------- +variable "env_prefix" { + type = string + description = "Shorthand name for the environment. Used in resource descriptions" +} + +variable "azure_region" { + type = string + description = "Region which Cloud resources will be created" +} + +variable "env_tags" { + type = map(any) + description = "Tags applied to provised resources" + + default = null +} + +# ------- Security Group settings ------- +variable "ingress_extra_cidrs_and_ports" { + type = object({ + cidrs = list(string) + ports = list(number) + }) + description = "List of extra CIDR blocks and ports to include in Security Group Ingress rules" + + default = { + cidrs = [], + ports = [] + } +} diff --git a/modules/terraform-azure-ingress/examples/ex02-existing_sgs/main.tf b/modules/terraform-azure-ingress/examples/ex02-existing_sgs/main.tf new file mode 100644 index 0000000..cd32726 --- /dev/null +++ b/modules/terraform-azure-ingress/examples/ex02-existing_sgs/main.tf @@ -0,0 +1,81 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_version = ">= 1.5.7" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 4.0.0" + } + } +} + +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } + +} + +# ------- Azure Resource Group ------- +module "rmgp" { + source = "../../../terraform-azure-resource-group" + + resourcegroup_name = "${var.env_prefix}-rg" + azure_region = var.azure_region + + tags = merge(var.env_tags, { Name = "${var.env_prefix}-rg" }) +} + +# Create security groups to pass in to module as pre-existing SGs +resource "azurerm_network_security_group" "cdp_default_sg" { + name = "${var.env_prefix}-existing-default-sg" + location = var.azure_region + resource_group_name = module.rmgp.resource_group_name + + tags = merge(var.env_tags, { Name = "${var.env_prefix}-existing-default-sg" }) + +} + +resource "azurerm_network_security_group" "cdp_knox_sg" { + name = "${var.env_prefix}-existing-knox-sg" + location = var.azure_region + resource_group_name = module.rmgp.resource_group_name + + tags = merge(var.env_tags, { Name = "${var.env_prefix}-existing-knox-sg" }) + +} + +# ------- Azure SGs ------- +module "ex02_sg" { + source = "../.." + + resource_group_name = module.rmgp.resource_group_name + azure_region = var.azure_region + + existing_default_security_group_name = azurerm_network_security_group.cdp_default_sg.name + existing_knox_security_group_name = azurerm_network_security_group.cdp_knox_sg.name + + # default_security_group_name = "${var.env_prefix}-default-sg" + # knox_security_group_name = "${var.env_prefix}-knox-sg" + + # ingress_extra_cidrs_and_ports = var.ingress_extra_cidrs_and_ports + + # tags = var.env_tags + + depends_on = [module.rmgp] +} diff --git a/modules/terraform-azure-ingress/examples/ex02-existing_sgs/outputs.tf b/modules/terraform-azure-ingress/examples/ex02-existing_sgs/outputs.tf new file mode 100644 index 0000000..6516d37 --- /dev/null +++ b/modules/terraform-azure-ingress/examples/ex02-existing_sgs/outputs.tf @@ -0,0 +1,25 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +output "azure_security_group_default_uri" { + value = module.ex02_sg.azure_default_security_group_uri + + description = "Azure Default Security Group URI" +} + +output "azure_knox_security_group_uri" { + value = module.ex02_sg.azure_knox_security_group_uri + + description = "Azure Knox Security Group URI" +} diff --git a/modules/terraform-azure-ingress/examples/ex02-existing_sgs/terraform.tfvars.sample b/modules/terraform-azure-ingress/examples/ex02-existing_sgs/terraform.tfvars.sample new file mode 100644 index 0000000..6cc3953 --- /dev/null +++ b/modules/terraform-azure-ingress/examples/ex02-existing_sgs/terraform.tfvars.sample @@ -0,0 +1,27 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ------- Global settings ------- +env_prefix = "" # Required name prefix for cloud and CDP resources, e.g. cldr1 + +# ------- Cloud Settings ------- +azure_region = "" # Change this to specify Cloud Provider region, e.g. eastus + +# ------- Resource Tagging ------- +# **NOTE: An example of how to specify tags is below; uncomment & edit if required +# env_tags = { +# owner = "" +# project = "" +# enddate = "" +# } diff --git a/modules/terraform-azure-ingress/examples/ex02-existing_sgs/variables.tf b/modules/terraform-azure-ingress/examples/ex02-existing_sgs/variables.tf new file mode 100644 index 0000000..bd02be5 --- /dev/null +++ b/modules/terraform-azure-ingress/examples/ex02-existing_sgs/variables.tf @@ -0,0 +1,45 @@ +# Copyright 2023 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ------- Global settings ------- +variable "env_prefix" { + type = string + description = "Shorthand name for the environment. Used in resource descriptions" +} + +variable "azure_region" { + type = string + description = "Region which Cloud resources will be created" +} + +variable "env_tags" { + type = map(any) + description = "Tags applied to provised resources" + + default = null +} + +# ------- Security Group settings ------- +variable "ingress_extra_cidrs_and_ports" { + type = object({ + cidrs = list(string) + ports = list(number) + }) + description = "List of extra CIDR blocks and ports to include in Security Group Ingress rules" + + default = { + cidrs = [], + ports = [] + } +} diff --git a/modules/terraform-azure-ingress/main.tf b/modules/terraform-azure-ingress/main.tf new file mode 100644 index 0000000..9ae2749 --- /dev/null +++ b/modules/terraform-azure-ingress/main.tf @@ -0,0 +1,75 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Default SG +resource "azurerm_network_security_group" "cdp_default_sg" { + + count = local.create_default_security_group ? 1 : 0 + + name = var.default_security_group_name + location = var.azure_region + resource_group_name = var.resource_group_name + + tags = merge(var.tags, { Name = var.default_security_group_name }) + +} + +# Create security group rules for extra list of ingress rules +resource "azurerm_network_security_rule" "cdp_default_sg_ingress_extra_access" { + + count = local.create_default_security_group ? 1 : 0 + + name = "AllowAccessForExtraCidrsAndPorts" + priority = var.default_security_group_ingress_priority + direction = "Inbound" + access = "Allow" + protocol = var.default_security_group_ingress_protocol + source_address_prefixes = var.ingress_extra_cidrs_and_ports.cidrs + destination_address_prefix = var.default_security_group_ingress_destination_address_prefix + source_port_range = "*" + destination_port_ranges = var.ingress_extra_cidrs_and_ports.ports + resource_group_name = var.resource_group_name + network_security_group_name = azurerm_network_security_group.cdp_default_sg[0].name +} + +# Knox SG +resource "azurerm_network_security_group" "cdp_knox_sg" { + + count = local.create_knox_security_group ? 1 : 0 + + name = var.knox_security_group_name + location = var.azure_region + resource_group_name = var.resource_group_name + + tags = merge(var.tags, { Name = var.knox_security_group_name }) + +} + +# Create security group rules for extra list of ingress rules +resource "azurerm_network_security_rule" "cdp_knox_sg_ingress_extra_access" { + + count = local.create_knox_security_group ? 1 : 0 + + name = "AllowAccessForExtraCidrsAndPorts" + priority = var.knox_security_group_ingress_priority + direction = "Inbound" + access = "Allow" + protocol = var.knox_security_group_ingress_protocol + source_address_prefixes = var.ingress_extra_cidrs_and_ports.cidrs + destination_address_prefix = var.knox_security_group_ingress_destination_address_prefix + source_port_range = "*" + destination_port_ranges = var.ingress_extra_cidrs_and_ports.ports + resource_group_name = var.resource_group_name + network_security_group_name = azurerm_network_security_group.cdp_knox_sg[0].name +} \ No newline at end of file diff --git a/modules/terraform-azure-ingress/outputs.tf b/modules/terraform-azure-ingress/outputs.tf new file mode 100644 index 0000000..44f62e9 --- /dev/null +++ b/modules/terraform-azure-ingress/outputs.tf @@ -0,0 +1,25 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +output "azure_default_security_group_uri" { + value = data.azurerm_network_security_group.cdp_default_sg.id + + description = "Azure Default Security Group URI" +} + +output "azure_knox_security_group_uri" { + value = data.azurerm_network_security_group.cdp_knox_sg.id + + description = "Azure Knox Security Group URI" +} diff --git a/modules/terraform-azure-ingress/provider.tf b/modules/terraform-azure-ingress/provider.tf new file mode 100644 index 0000000..bfa72a4 --- /dev/null +++ b/modules/terraform-azure-ingress/provider.tf @@ -0,0 +1,25 @@ +# Copyright 2024 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 4.0.0" + } + } + + required_version = ">= 1.9.0" +} + diff --git a/modules/terraform-azure-ingress/variables.tf b/modules/terraform-azure-ingress/variables.tf new file mode 100644 index 0000000..2367d34 --- /dev/null +++ b/modules/terraform-azure-ingress/variables.tf @@ -0,0 +1,142 @@ +# Copyright 2025 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ------- Global settings ------- +variable "azure_region" { + type = string + description = "Region which Cloud resources will be created" + +} + +variable "tags" { + type = map(any) + description = "Tags applied to provised resources" + + default = null +} + + +# ------- Azure specific settings ------- +variable "resource_group_name" { + type = string + description = "Azrue Resource Group for Managed Identities." + +} + +# Security Groups +variable "default_security_group_name" { + type = string + + description = "Default Security Group for Cloudera on cloud environment" + + default = null + + validation { + condition = (var.default_security_group_name == null ? true : length(var.default_security_group_name) >= 1 && length(var.default_security_group_name) <= 80) + error_message = "The length of default_security_group_name must be 80 characters or less." + } + + validation { + condition = (var.default_security_group_name == null ? true : can(regex("^[a-zA-Z0-9\\-\\_\\.]{1,80}$", var.default_security_group_name))) + error_message = "default_security_group_name can consist only of letters, numbers, dots (.), hyphens (-) and underscores (_)." + } +} + +variable "knox_security_group_name" { + type = string + + description = "Knox Security Group for CCloudera on cloud environment" + + default = null + + validation { + condition = (var.knox_security_group_name == null ? true : length(var.knox_security_group_name) >= 1 && length(var.knox_security_group_name) <= 80) + error_message = "The length of knox_security_group_name must be 80 characters or less." + } + + validation { + condition = (var.knox_security_group_name == null ? true : can(regex("^[a-zA-Z0-9\\-\\_\\.]{1,80}$", var.knox_security_group_name))) + error_message = "knox_security_group_name can consist only of letters, numbers, dots (.), hyphens (-) and underscores (_)." + } +} + +variable "ingress_extra_cidrs_and_ports" { + type = object({ + cidrs = list(string) + ports = list(number) + }) + description = "List of extra CIDR blocks and ports to include in Security Group Ingress rules" + + default = { + cidrs = [], + ports = [] + } +} + +variable "default_security_group_ingress_protocol" { + type = string + description = "Protocol for Default Security Group Ingress rules" + + default = "Tcp" +} + +variable "default_security_group_ingress_priority" { + type = number + description = "Priority for Default Security Group Ingress rules" + + default = 201 +} + +variable "default_security_group_ingress_destination_address_prefix" { + type = string + description = "Destination address prefix for Default Security Group Ingress rules" + + default = "*" +} + +variable "knox_security_group_ingress_protocol" { + type = string + description = "Protocol for Knox Security Group Ingress rules" + + default = "Tcp" +} + +variable "knox_security_group_ingress_priority" { + type = number + description = "Priority for Knox Security Group Ingress rules" + + default = 201 +} + +variable "knox_security_group_ingress_destination_address_prefix" { + type = string + description = "Destination address prefix for Knox Security Group Ingress rules" + + default = "*" +} + +# ------- Support for existing Security Groups ------- +variable "existing_default_security_group_name" { + type = string + description = "Name of existing Default Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Default SG." + + default = null +} + +variable "existing_knox_security_group_name" { + type = string + description = "Name of existing Knox Security Group for Cloudera on cloud environment. If set then no security group or ingress rules are created for the Knox SG." + + default = null +} diff --git a/modules/terraform-cdp-azure-pre-reqs/README.md b/modules/terraform-cdp-azure-pre-reqs/README.md index ed52f28..10e9823 100644 --- a/modules/terraform-cdp-azure-pre-reqs/README.md +++ b/modules/terraform-cdp-azure-pre-reqs/README.md @@ -31,6 +31,7 @@ In each directory an example `terraform.tfvars.sample` values file is included t | Name | Source | Version | |------|--------|---------| +| [azure\_cdp\_ingress](#module\_azure\_cdp\_ingress) | ../terraform-azure-ingress | n/a | | [azure\_cdp\_rmgp](#module\_azure\_cdp\_rmgp) | ../terraform-azure-resource-group | n/a | | [azure\_cdp\_vnet](#module\_azure\_cdp\_vnet) | ../terraform-azure-vnet | n/a | | [azure\_cloudera\_cred\_permissions](#module\_azure\_cloudera\_cred\_permissions) | ../terraform-azure-cred-permissions | n/a | @@ -42,10 +43,6 @@ In each directory an example `terraform.tfvars.sample` values file is included t | Name | Type | |------|------| -| [azurerm_network_security_group.cdp_default_sg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group) | resource | -| [azurerm_network_security_group.cdp_knox_sg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group) | resource | -| [azurerm_network_security_rule.cdp_default_sg_ingress_extra_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_rule) | resource | -| [azurerm_network_security_rule.cdp_knox_sg_ingress_extra_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_rule) | resource | | [azurerm_private_dns_zone.flexible_server_dns_zone](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone) | resource | | [azurerm_private_dns_zone_virtual_network_link.flexible_server_vnet_link](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone_virtual_network_link) | resource | | [azurerm_role_assignment.cdp_datalake_admin_backup_container_assign](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | diff --git a/modules/terraform-cdp-azure-pre-reqs/main.tf b/modules/terraform-cdp-azure-pre-reqs/main.tf index 1443a7a..f03a592 100644 --- a/modules/terraform-cdp-azure-pre-reqs/main.tf +++ b/modules/terraform-cdp-azure-pre-reqs/main.tf @@ -89,57 +89,20 @@ module "azure_cdp_vnet" { } # ------- Security Groups ------- -# Default SG -resource "azurerm_network_security_group" "cdp_default_sg" { - name = local.security_group_default_name - location = module.azure_cdp_rmgp.resource_group_location - resource_group_name = var.separate_network_resource_group ? module.azure_network_rmgp[0].resource_group_name : module.azure_cdp_rmgp.resource_group_name +# Default and Knox SG +module "azure_cdp_ingress" { - tags = merge(local.env_tags, { Name = local.security_group_default_name }) + source = "../terraform-azure-ingress" -} - -# Create security group rules for extra list of ingress rules -# TODO: How to handle the case where ingress_extra_cidrs_and_ports is [] -resource "azurerm_network_security_rule" "cdp_default_sg_ingress_extra_access" { - name = "AllowAccessForExtraCidrsAndPorts" - priority = 201 - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_address_prefixes = var.ingress_extra_cidrs_and_ports.cidrs - destination_address_prefix = "*" - source_port_range = "*" - destination_port_ranges = var.ingress_extra_cidrs_and_ports.ports - resource_group_name = var.separate_network_resource_group ? module.azure_network_rmgp[0].resource_group_name : module.azure_cdp_rmgp.resource_group_name - network_security_group_name = azurerm_network_security_group.cdp_default_sg.name -} - -# Knox SG -resource "azurerm_network_security_group" "cdp_knox_sg" { - name = local.security_group_knox_name - location = module.azure_cdp_rmgp.resource_group_location resource_group_name = var.separate_network_resource_group ? module.azure_network_rmgp[0].resource_group_name : module.azure_cdp_rmgp.resource_group_name + azure_region = var.azure_region - tags = merge(local.env_tags, { Name = local.security_group_knox_name }) - -} + default_security_group_name = local.security_group_default_name + knox_security_group_name = local.security_group_knox_name + ingress_extra_cidrs_and_ports = var.ingress_extra_cidrs_and_ports + tags = local.env_tags -# Create security group rules for extra list of ingress rules -# TODO: How to handle the case where ingress_extra_cidrs_and_ports is [] -resource "azurerm_network_security_rule" "cdp_knox_sg_ingress_extra_access" { - name = "AllowAccessForExtraCidrsAndPorts" - priority = 201 - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_address_prefixes = var.ingress_extra_cidrs_and_ports.cidrs - destination_address_prefix = "*" - source_port_range = "*" - destination_port_ranges = var.ingress_extra_cidrs_and_ports.ports - resource_group_name = var.separate_network_resource_group ? module.azure_network_rmgp[0].resource_group_name : module.azure_cdp_rmgp.resource_group_name - network_security_group_name = azurerm_network_security_group.cdp_knox_sg.name } # ------- Azure Storage Account ------- diff --git a/modules/terraform-cdp-azure-pre-reqs/outputs.tf b/modules/terraform-cdp-azure-pre-reqs/outputs.tf index a80413c..2c839ee 100644 --- a/modules/terraform-cdp-azure-pre-reqs/outputs.tf +++ b/modules/terraform-cdp-azure-pre-reqs/outputs.tf @@ -78,13 +78,13 @@ output "azure_database_private_dns_zone_id" { } output "azure_security_group_default_uri" { - value = azurerm_network_security_group.cdp_default_sg.id + value = module.azure_cdp_ingress.azure_default_security_group_uri description = "Azure Default Security Group URI" } output "azure_security_group_knox_uri" { - value = azurerm_network_security_group.cdp_knox_sg.id + value = module.azure_cdp_ingress.azure_knox_security_group_uri description = "Azure Knox Security Group URI" }