Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
# Terraform Modules for Cloudera on Premise Community Edition Infrastructure Creation on <ENTER_INFRA_PROVIDER>
# Terraform Modules for Cloudera on Premise Community Edition Infrastructure Creation on AWS

This repository contains a number of Terraform modules for creation of infrastructure resources for Cloudera on premise clusters on <ENTER_INFRA_PROVIDER>. These modules support deployment of the Community Edition reference cluster.
This repository contains a number of Terraform modules for creation of infrastructure resources for Cloudera on premise clusters on AWS. These modules support deployment of the Community Edition reference cluster.

## Modules

| Module name | Description |
| ----------- | ----------- |
| [hosts](modules/hosts/README.md) | <ENTER_SHORT_DESCRIPTION> |
| [network](modules/network/README.md) | Creates and manages AWS networking infrastructure with public/private subnets, NAT gateways, route tables, and security groups for Cloudera on premise deployments. |
| [hosts](modules/hosts/README.md) | Provisions and manages AWS EC2 instances with flexible configuration for compute resources, storage volumes, and networking designed for Cloudera on premise deployments. |

Each module contains Terraform resource configuration and example variable definition files.

## Usage

The [TODO: CE Public Repo](https://github.com/cloudera-labs/community-edition) repository demonstrates how to use the modules together to deploy the infrastructure for a Cloudera on premise cluster.
52 changes: 40 additions & 12 deletions modules/hosts/README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,72 @@
<!-- BEGIN_TF_DOCS -->
# Terraform Module for Hosts on ENTER\_INFRA\_PROVIDER
# Terraform Module for AWS Hosts

> [!IMPORTANT]
> This readme is automation generated using the [`terraform-docs`](https://terraform-docs.io/) command with the static contenta taken from [doc\_fragments/header.md](doc\_fragments/header.md)

The `hosts` module contains resource files to provision and manage <ENTER\_INFRA\_PROVIDER> instances with flexible configuration options for compute resources, storage volumes, and networking. This module is designed for Cloudera on premise infrastructure deployments on <ENTER\_INFRA\_PROVIDER>.
The `hosts` module contains resource files to provision and manage AWS EC2 instances with flexible configuration options for compute resources, storage volumes, and networking. This module is designed for Cloudera on premise infrastructure deployments on AWS IaaS but can be used for any AWS EC2 instance provisioning needs.

## Key Features

<ENTER\_KEY\_FEATURES>
- **Flexible Instance Provisioning**: Create single instances or multiple identical nodes with sequential naming
- **Custom Storage Configuration**: Attach and manage additional EBS volumes with configurable size, type, and mount points
- **Network Integration**: Place instances in specific subnets with optional public IP assignment
- **Security Management**: Apply security groups to control access to instances
- **Resource Tagging**: Add custom tags to all provisioned resources for better organization and cost management
- **IMDSv2 Support**: Automatic detection and configuration of IMDSv2 tokens based on AMI capabilities

## Usage

The [examples](./examples) directory has example of using this module:

* `ex01-minimal_inputs` demonstrates how this module can be used to create a number of hosts.
* `ex01-minimal_inputs` demonstrates how this module can be used to create a number of EC2 instances. The [terraform-aws-network](../terraform-aws-network/README.md) module is also used as part of this example.

The sample `terraform.tfvars.sample` describes the required inputs for the example.

## Requirements

No requirements.
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.60.0 |

## Providers

No providers.
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.60.0 |

## Modules

No modules.

## Resources

No resources.
| Name | Type |
|------|------|
| [aws_ebs_volume.inventory](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume) | resource |
| [aws_instance.pvc_base](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource |
| [aws_volume_attachment.inventory](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/volume_attachment) | resource |
| [aws_ami.pvc_base](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |

## Inputs

No inputs.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_image_id"></a> [image\_id](#input\_image\_id) | AMI image ID for the hosts | `string` | n/a | yes |
| <a name="input_name"></a> [name](#input\_name) | Instance name. If 'quantity' is set, name will be <name>-NN. | `string` | n/a | yes |
| <a name="input_security_groups"></a> [security\_groups](#input\_security\_groups) | List of security group IDs to attach to the instances | `list(string)` | n/a | yes |
| <a name="input_ssh_key_pair"></a> [ssh\_key\_pair](#input\_ssh\_key\_pair) | SSH key pair name | `string` | n/a | yes |
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | List of subnet IDs to provision the instances | `list(string)` | n/a | yes |
| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | Instance type name for the hosts | `string` | `"t2.micro"` | no |
| <a name="input_offset"></a> [offset](#input\_offset) | Number offset for instance name | `number` | `0` | no |
| <a name="input_public_ip"></a> [public\_ip](#input\_public\_ip) | Flag to assign public IP addresses to the hosts | `bool` | `false` | no |
| <a name="input_quantity"></a> [quantity](#input\_quantity) | Number of instances. Defaults to a single instance without numbering (bare name). | `number` | `0` | no |
| <a name="input_root_volume"></a> [root\_volume](#input\_root\_volume) | Root volume details | <pre>object({<br/> delete_on_termination = optional(bool, true)<br/> volume_size = optional(number, 100)<br/> volume_type = optional(string)<br/> })</pre> | `{}` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Map of tags applied to all cloud-provider assets. | `map(any)` | `{}` | no |
| <a name="input_volumes"></a> [volumes](#input\_volumes) | Additional storage volumes to attach to the hosts. Each volume is defined by a device name, mount point, size, type, and optional tags. | <pre>list(object({<br/> device_name = string<br/> mount = string<br/> volume_size = optional(number, 100)<br/> volume_type = optional(string, "gp2")<br/> tags = optional(map(string), {})<br/> }<br/> )<br/> )</pre> | `null` | no |

## Outputs

No outputs.
| Name | Description |
|------|-------------|
| <a name="output_hosts"></a> [hosts](#output\_hosts) | Hosts |
| <a name="output_storage_volumes"></a> [storage\_volumes](#output\_storage\_volumes) | Additional Storage Volumes |
<!-- END_TF_DOCS -->
16 changes: 9 additions & 7 deletions modules/hosts/doc_fragments/header.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# Terraform Module for Hosts on ENTER_INFRA_PROVIDER
# Terraform Module for AWS Hosts

> [!IMPORTANT]
> This readme is automation generated using the [`terraform-docs`](https://terraform-docs.io/) command with the static contenta taken from [doc_fragments/header.md](doc_fragments/header.md)

The `hosts` module contains resource files to provision and manage <ENTER_INFRA_PROVIDER> instances with flexible configuration options for compute resources, storage volumes, and networking. This module is designed for Cloudera on premise infrastructure deployments on <ENTER_INFRA_PROVIDER>.
The `hosts` module contains resource files to provision and manage AWS EC2 instances with flexible configuration options for compute resources, storage volumes, and networking. This module is designed for Cloudera on premise infrastructure deployments on AWS IaaS but can be used for any AWS EC2 instance provisioning needs.

## Key Features

<ENTER_KEY_FEATURES>
- **Flexible Instance Provisioning**: Create single instances or multiple identical nodes with sequential naming
- **Custom Storage Configuration**: Attach and manage additional EBS volumes with configurable size, type, and mount points
- **Network Integration**: Place instances in specific subnets with optional public IP assignment
- **Security Management**: Apply security groups to control access to instances
- **Resource Tagging**: Add custom tags to all provisioned resources for better organization and cost management
- **IMDSv2 Support**: Automatic detection and configuration of IMDSv2 tokens based on AMI capabilities

## Usage

The [examples](./examples) directory has example of using this module:

* `ex01-minimal_inputs` demonstrates how this module can be used to create a number of hosts.
* `ex01-minimal_inputs` demonstrates how this module can be used to create a number of EC2 instances. The [terraform-aws-network](../terraform-aws-network/README.md) module is also used as part of this example.

The sample `terraform.tfvars.sample` describes the required inputs for the example.
111 changes: 108 additions & 3 deletions modules/hosts/examples/ex01-minimal_inputs/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,117 @@
# limitations under the License.

provider "aws" {
region = var.aws_region
region = var.region
default_tags {
tags = var.asset_tags
}
}

# ------- VPC -------

resource "aws_vpc" "ex01" {
cidr_block = var.vpc_cidr
tags = { Name = "${var.prefix}-vpc" }
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
}

resource "aws_internet_gateway" "ex01" {
vpc_id = aws_vpc.ex01.id
tags = { Name = "${var.prefix}-igw" }
}

resource "aws_vpc_dhcp_options" "ex01" {
domain_name = "${var.prefix}.cldr.internal"
domain_name_servers = ["AmazonProvidedDNS"]

tags = { Name = "${var.prefix}-vpc-dhcp-options" }
}

resource "aws_vpc_dhcp_options_association" "ex01" {
vpc_id = aws_vpc.ex01.id
dhcp_options_id = aws_vpc_dhcp_options.ex01.id
}

# ------- Network Module -------
module "ex01_network" {
source = "../../../network"

region = var.region
prefix = var.prefix
vpc_id = aws_vpc.ex01.id

}

resource "aws_security_group" "ssh" {
vpc_id = aws_vpc.ex01.id
name = "${var.prefix}-sg-ssh"
description = "SSH traffic [${var.prefix}]"
tags = { Name = "${var.prefix}-sg-ssh" }
}

resource "aws_vpc_security_group_ingress_rule" "ssh" {
for_each = toset(var.ingress_ssh_cidrs)

security_group_id = aws_security_group.ssh.id
description = "SSH traffic from ${each.value}"
cidr_ipv4 = each.value
from_port = 22
ip_protocol = "tcp"
to_port = 22
tags = { Name = "${var.prefix}-ssh-${index(var.ingress_ssh_cidrs, each.value)}" }
}

# ------- Host Module -------
module "ex01_hosts" {
source = "../.."
source = "../.."
depends_on = [aws_key_pair.ex01, data.aws_ami.ex01]

# <ENTER_REQUIRED_INPUTS>
name = "${var.prefix}-host"
quantity = 2
image_id = data.aws_ami.ex01.image_id
instance_type = "t2.micro"
subnet_ids = module.ex01_network.public_subnets[*].id # Will use the first public subnet
ssh_key_pair = aws_key_pair.ex01.key_name
security_groups = [
module.ex01_network.intra_cluster_security_group.id,
aws_security_group.ssh.id
]
public_ip = true
}

# ------- AMI -------
locals {
ami_owners = ["amazon"]
ami_filters = {
name = ["al2023-ami-2023*"]
architecture = ["x86_64"]
}
}

data "aws_ami" "ex01" {
owners = local.ami_owners
most_recent = true

dynamic "filter" {
for_each = local.ami_filters

content {
name = filter.key
values = filter.value
}
}
}

# ------- SSH -------

data "tls_public_key" "ex01" {
private_key_openssh = file(var.ssh_private_key_file)
}

resource "aws_key_pair" "ex01" {
key_name = "${var.prefix}-key"
public_key = trimspace(data.tls_public_key.ex01.public_key_openssh)
}

34 changes: 34 additions & 0 deletions modules/hosts/examples/ex01-minimal_inputs/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 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 "ssh_key_pair" {
value = {
name = aws_key_pair.ex01.key_name
public_key = trimspace(data.tls_public_key.ex01.public_key_openssh)
type = aws_key_pair.ex01.key_type
fingerprint = aws_key_pair.ex01.fingerprint
}
description = "SSH public key"
}

output "vpc" {
value = aws_vpc.ex01.id
description = "AWS VPC"
}

output "nodes" {
value = values(module.ex01_hosts)

description = "Node information including IDs, names, private and public IPs"
}
19 changes: 15 additions & 4 deletions modules/hosts/examples/ex01-minimal_inputs/terraform.tfvars.sample
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# <ENTER_REQUIRED_INPUT_VALUES>

# ------- Global Settings -------
name_prefix = "<ENTER_VALUE>"
prefix = "ex01"

region = "<ENTER_VALUE>" # Change this to specify Cloud Provider region, e.g. eu-west-1

asset_tags = {
"Environment" = "Development"
}

# ------- Network settings -------
ingress_ssh_cidrs = [
"<ENTER_CIDR>",
"<ENTER_CIDR>"
]

# ------- Cloud Settings -------
# ------- SSH settings -------
ssh_private_key_file = "<ENTER_SSH_PRIVATE_KEY_FILE_PATH>" # Path to the SSH
44 changes: 39 additions & 5 deletions modules/hosts/examples/ex01-minimal_inputs/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,46 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# <ENTER_REQUIRED_INPUT_VARIABLES>
# ------- General and Provider Resources -------

# ------- Global settings -------
variable "name_prefix" {
variable "prefix" {
type = string
description = "Shorthand name to use when naming resources."
description = "Deployment prefix for all cloud-provider assets"

validation {
condition = length(var.prefix) < 8 || length(var.prefix) > 4
error_message = "Valid length for prefix is between 4-7 characters."
}
}

variable "region" {
type = string
description = "AWS region"
}

# ------- Cloud Settings -------
variable "asset_tags" {
type = map(string)
default = {}
description = "Map of tags applied to all cloud-provider assets"
}

# ------- Network Resources -------
variable "vpc_cidr" {
type = string
description = "VPC CIDR Block (primary)"
default = "10.10.0.0/16"
}

variable "ingress_ssh_cidrs" {
type = list(string)
description = "List of CIDRs to add to ingress SSH inbound rules."

default = []
}

# ------- SSH Resources -------

variable "ssh_private_key_file" {
type = string
description = "Local SSH private key file"
}
Loading