From a347f39027a41ff6e5d0ea2b075f9c48d3cc1847 Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Wed, 7 Jul 2021 10:06:49 -0500 Subject: [PATCH 01/28] updated for Cloud Cluster ES --- main.tf | 51 ++++++++++----------------------------------------- variables.tf | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/main.tf b/main.tf index 2861eb2..4314b72 100644 --- a/main.tf +++ b/main.tf @@ -24,11 +24,11 @@ data "aws_subnet" "rubrik_cloud_cluster" { } data "aws_ami_ids" "rubrik_cloud_cluster" { - owners = ["679593333241"] + owners = var.aws_ami_owners filter { name = "name" - values = ["rubrik-mp-cc-*"] + values = var.aws_ami_filter } } @@ -123,45 +123,14 @@ resource "aws_instance" "rubrik_cluster" { encrypted = true } - ebs_block_device { - device_name = "/dev/sdb" - volume_type = "${var.cluster_disk_type}" - volume_size = "${var.cluster_disk_size}" - encrypted = true + dynamic "ebs_block_device" { + for_each = range(var.cluster_disk_count) + content{ + device_name = "/dev/sd${substr("bcdefghi",ebs_block_device.value,1)}" + volume_type = "${var.cluster_disk_type}" + volume_size = "${var.cluster_disk_size}" + encrypted = true + } } - ebs_block_device { - device_name = "/dev/sdc" - volume_type = "${var.cluster_disk_type}" - volume_size = "${var.cluster_disk_size}" - encrypted = true - } - - ebs_block_device { - device_name = "/dev/sdd" - volume_type = "${var.cluster_disk_type}" - volume_size = "${var.cluster_disk_size}" - encrypted = true - } - - ebs_block_device { - device_name = "/dev/sde" - volume_type = "${var.cluster_disk_type}" - volume_size = "${var.cluster_disk_size}" - encrypted = true - } - - ebs_block_device { - device_name = "/dev/sdf" - volume_type = "${var.cluster_disk_type}" - volume_size = "${var.cluster_disk_size}" - encrypted = true - } - - ebs_block_device { - device_name = "/dev/sdg" - volume_type = "${var.cluster_disk_type}" - volume_size = "${var.cluster_disk_size}" - encrypted = true - } } \ No newline at end of file diff --git a/variables.tf b/variables.tf index e2e2318..3e63c1f 100644 --- a/variables.tf +++ b/variables.tf @@ -45,6 +45,12 @@ variable "cluster_disk_size" { default = "1024" } +variable "cluster_disk_count" { + description = "The number of disks for each node in the cluster. Set to 0 to use with S3 storage for Cloud Cluster ES" + type = number + default = 4 +} + variable "cluster_name" { description = "Unique name to assign to the Rubrik Cloud Cluster. This will also be used to populate the EC2 instance name tag. For example, rubrik-cloud-cluster-1, rubrik-cloud-cluster-2 etc." default = "rubrik-cloud-cluster" @@ -78,3 +84,15 @@ variable "timeout" { description = "The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error." default = 15 } + +variable "aws_ami_owners" { + description = "Set of AWS Account that own the Rubrik Cloud Cluster AMI" + type = set(string) + default = ["679593333241"] +} + +variable "aws_ami_filter" { + description = "Set of AWS AMI names to search for" + type = set(string) + default = ["rubrik-mp-cc-*"] +} \ No newline at end of file From 7c0aed1a8928a2013a2dd3cc8469ec618a3535a6 Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Wed, 7 Jul 2021 10:15:25 -0500 Subject: [PATCH 02/28] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f5e7d8..4c1d0a0 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ The following are the variables accepted by the module. | aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | | number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 4 | no | | cluster_disk_type | The disk type to use for Rubrik Cloud Cluster data disks (sc1 or st1). NOTE: st1 disks require six 8TB disks. | string | st1 | yes | -| cluster_disk_size | The size of each the three data disks in each node. | string | 1024 | no | +| cluster_disk_count | The number of disks to use per node. Set to zero to leverage S3 object storage if deploying Cloud Cluster ES | number | 4 | no | | cluster_name | Unique name to assign to Rubrik Cloud Cluster. Also used for EC2 instance name tag. For example, rubrik-1, rubrik-2 etc. | string | | yes | | admin_email | The Rubrik Cloud Cluster sends messages for the admin account to this email address. | string | | yes | | admin_password | Password for the Rubrik Cloud Cluster admin account. | string | RubrikGoForward | no | From 6c9d590527fcf20f45c3a195268f0e2631fec958 Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Fri, 9 Jul 2021 08:50:46 -0500 Subject: [PATCH 03/28] working AWS CC ES!!! --- main.tf | 156 ++++++++++++++++++++++++++++++--------------------- output.tf | 6 +- providers.tf | 2 +- variables.tf | 36 +++++++++--- 4 files changed, 124 insertions(+), 76 deletions(-) diff --git a/main.tf b/main.tf index 4314b72..dd76da1 100644 --- a/main.tf +++ b/main.tf @@ -6,7 +6,7 @@ provider "aws" { # Dynamic Variable Creation # ############################# resource "null_resource" "create_cluster_node_name" { - count = "${var.number_of_nodes}" + count = var.number_of_nodes triggers = { node_number = "${count.index + 1}" @@ -14,13 +14,13 @@ resource "null_resource" "create_cluster_node_name" { } locals { - cluster_node_name = "${formatlist("${var.cluster_name}-%s", null_resource.create_cluster_node_name.*.triggers.node_number)}" + cluster_node_name = formatlist("${var.cluster_name}-%s", null_resource.create_cluster_node_name.*.triggers.node_number) - cluster_node_ips = "${aws_instance.rubrik_cluster.*.private_ip}" + cluster_node_ips = aws_instance.rubrik_cluster.*.private_ip } data "aws_subnet" "rubrik_cloud_cluster" { - id = "${var.aws_subnet_id}" + id = var.aws_subnet_id } data "aws_ami_ids" "rubrik_cloud_cluster" { @@ -38,7 +38,7 @@ data "aws_ami_ids" "rubrik_cloud_cluster" { resource "aws_key_pair" "rubrik_cloud_cluster" { key_name = "${var.cluster_name}-key-pair" - public_key = "${var.aws_public_key}" + public_key = var.aws_public_key } ######################################### @@ -46,59 +46,82 @@ resource "aws_key_pair" "rubrik_cloud_cluster" { ######################################### resource "aws_security_group" "rubrik_cloud_cluster" { - name = "${var.aws_vpc_security_group_name_cloud_cluster_nodes}" + name = var.aws_vpc_security_group_name_cloud_cluster_nodes description = "Allow hosts to talk to Rubrik Cloud Cluster" - vpc_id = "${data.aws_subnet.rubrik_cloud_cluster.vpc_id}" - - ingress { - description = "Intra cluster communication" - from_port = 0 - to_port = 0 - protocol = "-1" - self = true + vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id + tags = merge( + var.aws_tags, + { "sg:purpose" = "rubrik-cluster-to-self" } + ) + + lifecycle { + create_before_destroy = true } +} - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = ["::/0"] - } +resource "aws_security_group_rule" "rubrik_cloud_cluster_node_ingress" { + type = "ingress" + description = "Intra cluster communication" + from_port = 0 + to_port = 0 + protocol = "-1" + self = true + security_group_id = aws_security_group.rubrik_cloud_cluster.id } -resource "aws_security_group" "rubrik_hosts" { - name = "${var.aws_vpc_security_group_name_cloud_cluster_hosts}" - description = "Allow Rubrik Cloud Cluster to communicate with hosts" - vpc_id = "${data.aws_subnet.rubrik_cloud_cluster.vpc_id}" - - ingress { - description = "Ports for Rubrik Backup Service (RBS)" - from_port = 12800 - to_port = 12801 - protocol = "tcp" - security_groups = ["${aws_security_group.rubrik_cloud_cluster.id}"] - } +resource "aws_security_group_rule" "rubrik_cloud_cluster_node_egress" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + security_group_id = aws_security_group.rubrik_cloud_cluster.id } resource "aws_security_group_rule" "rubrik_cloud_cluster_cli_admin" { - type = "ingress" - description = "CLI administration of the nodes" - from_port = 22 - to_port = 22 - protocol = "tcp" - security_group_id = "${aws_security_group.rubrik_cloud_cluster.id}" - source_security_group_id = "${aws_security_group.rubrik_hosts.id}" + type = "ingress" + description = "CLI administration of the nodes" + from_port = 22 + to_port = 22 + protocol = "tcp" + security_group_id = aws_security_group.rubrik_cloud_cluster.id + source_security_group_id = aws_security_group.rubrik_hosts.id } resource "aws_security_group_rule" "rubrik_cloud_cluster_web_admin" { - type = "ingress" - description = "Web administration of the nodes" - from_port = 443 - to_port = 443 - protocol = "tcp" - security_group_id = "${aws_security_group.rubrik_cloud_cluster.id}" - source_security_group_id = "${aws_security_group.rubrik_hosts.id}" + type = "ingress" + description = "Web administration of the nodes" + from_port = 443 + to_port = 443 + protocol = "tcp" + security_group_id = aws_security_group.rubrik_cloud_cluster.id + source_security_group_id = aws_security_group.rubrik_hosts.id +} + + +resource "aws_security_group" "rubrik_hosts" { + name = var.aws_vpc_security_group_name_cloud_cluster_hosts + description = "Allow Rubrik Cloud Cluster to communicate with hosts" + vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id + tags = merge( + var.aws_tags, + { "sg:purpose" = "rubrik-cluster-to-self" } + ) + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_security_group_rule" "rubrik_cloud_cluster_rbs" { + type = "ingress" + description = "Ports for Rubrik Backup Service (RBS)" + from_port = 12800 + to_port = 12801 + protocol = "tcp" + security_group_id = aws_security_group.rubrik_hosts.id + source_security_group_id = aws_security_group.rubrik_cloud_cluster.id } ############################### @@ -106,29 +129,32 @@ resource "aws_security_group_rule" "rubrik_cloud_cluster_web_admin" { ############################### resource "aws_instance" "rubrik_cluster" { - count = "${var.number_of_nodes}" - instance_type = "${var.aws_instance_type}" - ami = "${element(data.aws_ami_ids.rubrik_cloud_cluster.ids, 0)}" - vpc_security_group_ids = ["${aws_security_group.rubrik_cloud_cluster.id}"] - subnet_id = "${var.aws_subnet_id}" - key_name = "${aws_key_pair.rubrik_cloud_cluster.key_name}" - - tags = { - Name = "${element(local.cluster_node_name, count.index)}" - } - - disable_api_termination = "${var.aws_disable_api_termination}" - + count = var.number_of_nodes + instance_type = var.aws_instance_type + ami = element(data.aws_ami_ids.rubrik_cloud_cluster.ids, 0) + vpc_security_group_ids = concat([ + aws_security_group.rubrik_cloud_cluster.id + ], var.aws_security_group_ids) + subnet_id = var.aws_subnet_id + key_name = aws_key_pair.rubrik_cloud_cluster.key_name + + tags = merge({ + Name = local.cluster_node_name[count.index] }, + var.aws_tags + ) + + disable_api_termination = var.aws_disable_api_termination + iam_instance_profile = var.aws_iam_instance_profile root_block_device { encrypted = true } - + dynamic "ebs_block_device" { for_each = range(var.cluster_disk_count) - content{ - device_name = "/dev/sd${substr("bcdefghi",ebs_block_device.value,1)}" - volume_type = "${var.cluster_disk_type}" - volume_size = "${var.cluster_disk_size}" + content { + device_name = "/dev/sd${substr("bcdefghi", ebs_block_device.value, 1)}" + volume_type = var.cluster_disk_type + volume_size = var.cluster_disk_size encrypted = true } } diff --git a/output.tf b/output.tf index b6266d8..dd7f95a 100644 --- a/output.tf +++ b/output.tf @@ -1,3 +1,7 @@ output "rubrik_cloud_cluster_ip_addrs" { - value = aws_instance.rubrik_cluster.*.private_ip + value = aws_instance.rubrik_cluster.*.private_ip +} + +output "rubrik_protected_hosts_security_group_id" { + value = aws_security_group.rubrik_hosts.id } \ No newline at end of file diff --git a/providers.tf b/providers.tf index b7bdbfd..00d6ffe 100644 --- a/providers.tf +++ b/providers.tf @@ -4,7 +4,7 @@ terraform { required_version = ">= 0.15.4" required_providers { aws = { - source = "hashicorp/aws" + source = "hashicorp/aws" } } } \ No newline at end of file diff --git a/variables.tf b/variables.tf index 3e63c1f..812ba72 100644 --- a/variables.tf +++ b/variables.tf @@ -21,6 +21,24 @@ variable "aws_vpc_security_group_name_cloud_cluster_hosts" { default = "Rubrik Cloud Cluster Hosts" } +variable "aws_security_group_ids" { + description = "Extra security groups to add to Rubrik cluster nodes" + type = list(string) + default = [] +} + +variable "aws_iam_instance_profile" { + description = "IAM instance profile for accessing S3 with Cloud Cluster ES" + type = string + default = "" +} + +variable "aws_tags" { + description = "Extra tags to add to Rubrik cluster nodes" + type = map(string) + default = {} +} + variable "aws_subnet_id" { description = "The VPC Subnet ID to launch Rubrik Cloud Cluster in." } @@ -47,8 +65,8 @@ variable "cluster_disk_size" { variable "cluster_disk_count" { description = "The number of disks for each node in the cluster. Set to 0 to use with S3 storage for Cloud Cluster ES" - type = number - default = 4 + type = number + default = 4 } variable "cluster_name" { @@ -60,18 +78,18 @@ variable "admin_email" { description = "The Rubrik Cloud Cluster sends messages for the admin account to this email address." } -variable admin_password { +variable "admin_password" { description = "Password for the Rubrik Cloud Cluster admin account." default = "RubrikGoForward" } variable "dns_search_domain" { - type = list + type = list(any) description = "List of search domains that the DNS Service will use to resolve hostnames that are not fully qualified." } variable "dns_name_servers" { - type = list + type = list(any) description = "List of the IPv4 addresses of the DNS servers." } @@ -87,12 +105,12 @@ variable "timeout" { variable "aws_ami_owners" { description = "Set of AWS Account that own the Rubrik Cloud Cluster AMI" - type = set(string) - default = ["679593333241"] + type = set(string) + default = ["679593333241"] } variable "aws_ami_filter" { description = "Set of AWS AMI names to search for" - type = set(string) - default = ["rubrik-mp-cc-*"] + type = set(string) + default = ["rubrik-mp-cc-*"] } \ No newline at end of file From 61b977d32c308e70c8e444855281ae96155aa2f9 Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Fri, 9 Jul 2021 15:03:45 -0500 Subject: [PATCH 04/28] updated style and implemented for_each --- main.tf | 57 +++++++++++++++++++++++++++++-------------------------- output.tf | 2 +- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/main.tf b/main.tf index dd76da1..b963cd1 100644 --- a/main.tf +++ b/main.tf @@ -1,22 +1,16 @@ -provider "aws" { - region = var.aws_region -} - ############################# # Dynamic Variable Creation # ############################# -resource "null_resource" "create_cluster_node_name" { - count = var.number_of_nodes - - triggers = { - node_number = "${count.index + 1}" - } -} - locals { - cluster_node_name = formatlist("${var.cluster_name}-%s", null_resource.create_cluster_node_name.*.triggers.node_number) - - cluster_node_ips = aws_instance.rubrik_cluster.*.private_ip + cluster_node_names = formatlist("${var.cluster_name}-%s", range(1, var.number_of_nodes + 1)) + cluster_node_ips = [for i in aws_instance.rubrik_cluster: i.private_ip] + cluster_disks = { + for v in setproduct(local.cluster_node_names,range(var.cluster_disk_count)) : + "${v[0]}-sd${substr("bcdefghi", v[1], 1)}" => { + "instance" = v[0], + "device" = "/dev/sd${substr("bcdefghi", v[1], 1)}" + } + } } data "aws_subnet" "rubrik_cloud_cluster" { @@ -129,9 +123,9 @@ resource "aws_security_group_rule" "rubrik_cloud_cluster_rbs" { ############################### resource "aws_instance" "rubrik_cluster" { - count = var.number_of_nodes + for_each = toset(local.cluster_node_names) instance_type = var.aws_instance_type - ami = element(data.aws_ami_ids.rubrik_cloud_cluster.ids, 0) + ami = data.aws_ami_ids.rubrik_cloud_cluster.ids[0] vpc_security_group_ids = concat([ aws_security_group.rubrik_cloud_cluster.id ], var.aws_security_group_ids) @@ -139,7 +133,7 @@ resource "aws_instance" "rubrik_cluster" { key_name = aws_key_pair.rubrik_cloud_cluster.key_name tags = merge({ - Name = local.cluster_node_name[count.index] }, + Name = each.value }, var.aws_tags ) @@ -149,14 +143,23 @@ resource "aws_instance" "rubrik_cluster" { encrypted = true } - dynamic "ebs_block_device" { - for_each = range(var.cluster_disk_count) - content { - device_name = "/dev/sd${substr("bcdefghi", ebs_block_device.value, 1)}" - volume_type = var.cluster_disk_type - volume_size = var.cluster_disk_size - encrypted = true - } - } +} + +resource "aws_ebs_volume" "ebs_block_device" { + for_each = local.cluster_disks + availability_zone = data.aws_subnet.rubrik_cloud_cluster.availability_zone + type = var.cluster_disk_type + size = var.cluster_disk_size + tags = merge( + {Name = each.key}, + var.aws_tags + ) + encrypted = true +} +resource "aws_volume_attachment" "ebs_att" { + for_each = local.cluster_disks + device_name = each.value.device + volume_id = aws_ebs_volume.ebs_block_device[each.key].id + instance_id = aws_instance.rubrik_cluster[each.value.instance].id } \ No newline at end of file diff --git a/output.tf b/output.tf index dd7f95a..c3469a9 100644 --- a/output.tf +++ b/output.tf @@ -1,5 +1,5 @@ output "rubrik_cloud_cluster_ip_addrs" { - value = aws_instance.rubrik_cluster.*.private_ip + value = local.cluster_node_ips } output "rubrik_protected_hosts_security_group_id" { From 8096c37e76c49d3759d899fc6fc46166ac7a6260 Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Sun, 11 Jul 2021 06:48:49 -0500 Subject: [PATCH 05/28] refactor for cloud cluster es --- cc_es_policy.json.tpl | 25 +++ main.tf | 222 ++++++++++++++------------- modules/iam_role/main.tf | 77 ++++++++++ modules/rubrik_aws_instances/main.tf | 65 ++++++++ modules/rubrik_hosts_sg/main.tf | 22 +++ modules/rubrik_hosts_sg/variables.tf | 17 ++ modules/rubrik_nodes_sg/main.tf | 48 ++++++ modules/rubrik_nodes_sg/variables.tf | 17 ++ modules/s3_vpc_endpoint/main.tf | 30 ++++ modules/s3_vpc_endpoint/output.tf | 4 + modules/s3_vpc_endpoint/variables.tf | 22 +++ output.tf | 8 +- variables.tf | 81 ++++++++-- 13 files changed, 518 insertions(+), 120 deletions(-) create mode 100644 cc_es_policy.json.tpl create mode 100644 modules/iam_role/main.tf create mode 100644 modules/rubrik_aws_instances/main.tf create mode 100644 modules/rubrik_hosts_sg/main.tf create mode 100644 modules/rubrik_hosts_sg/variables.tf create mode 100644 modules/rubrik_nodes_sg/main.tf create mode 100644 modules/rubrik_nodes_sg/variables.tf create mode 100644 modules/s3_vpc_endpoint/main.tf create mode 100644 modules/s3_vpc_endpoint/output.tf create mode 100644 modules/s3_vpc_endpoint/variables.tf diff --git a/cc_es_policy.json.tpl b/cc_es_policy.json.tpl new file mode 100644 index 0000000..c3eb893 --- /dev/null +++ b/cc_es_policy.json.tpl @@ -0,0 +1,25 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:AbortMultipartUpload", + "s3:DeleteObject*", + "s3:GetObject*", + "s3:ListMultipartUploadParts", + "s3:PutObject*" + ], + "Resource": "arn:aws:s3:::${resource}/*" + }, + { + "Effect": "Allow", + "Action": [ + "s3:GetBucket*", + "s3:ListBucket*" + ], + "Resource": "arn:aws:s3:::${resource}" + } + ] +} + diff --git a/main.tf b/main.tf index b963cd1..b6dc7ff 100644 --- a/main.tf +++ b/main.tf @@ -2,21 +2,40 @@ # Dynamic Variable Creation # ############################# locals { - cluster_node_names = formatlist("${var.cluster_name}-%s", range(1, var.number_of_nodes + 1)) - cluster_node_ips = [for i in aws_instance.rubrik_cluster: i.private_ip] + cluster_name = var.environment == "" ? var.cluster_name : "${var.environment}.${var.cluster_name}" + cluster_node_names = formatlist("${local.cluster_name}-%01s", range(1, var.number_of_nodes + 1)) + cluster_node_config = { + "instance_type" = var.aws_instance_type, + "ami_id" = data.aws_ami_ids.rubrik_cloud_cluster.ids[0], + "sg_ids" = concat(var.aws_cloud_cluster_nodes_sg_ids, [module.rubrik_nodes_sg.security_group_id]), + "subnet_id" = var.aws_subnet_id, + "key_pair_name" = local.aws_key_pair_name, + "disable_api_termination" = var.aws_disable_api_termination, + "iam_instance_profile" = module.iam_role.aws_iam_instance_profile.name, + "availability_zone" = data.aws_subnet.rubrik_cloud_cluster.availability_zone, + "tags" = var.aws_tags + } + cluster_node_ips = [for i in module.cluster_nodes.instances: i.private_ip] cluster_disks = { for v in setproduct(local.cluster_node_names,range(var.cluster_disk_count)) : "${v[0]}-sd${substr("bcdefghi", v[1], 1)}" => { "instance" = v[0], "device" = "/dev/sd${substr("bcdefghi", v[1], 1)}" + "size" = var.cluster_disk_size + "type" = var.cluster_disk_type } } + cluster_tag = var.environment_tag == "" ? local.cluster_name : "${var.environment_tag}:${local.cluster_name}" } data "aws_subnet" "rubrik_cloud_cluster" { id = var.aws_subnet_id } +data "aws_vpc" "rubrik_cloud_cluster" { + id = data.aws_subnet.rubrik_cloud_cluster.vpc_id +} + data "aws_ami_ids" "rubrik_cloud_cluster" { owners = var.aws_ami_owners @@ -30,136 +49,127 @@ data "aws_ami_ids" "rubrik_cloud_cluster" { # SSH KEY PAIR FOR INSTANCES # ############################## -resource "aws_key_pair" "rubrik_cloud_cluster" { - key_name = "${var.cluster_name}-key-pair" +module "aws_key_pair" { + source = "terraform-aws-modules/key-pair/aws" + + key_name = var.aws_key_pair_name == "" ? "${local.cluster_name}.key-pair" : var.aws_key_pair_name public_key = var.aws_public_key + create_key_pair = var.create_key_pair } -######################################### -# Security Group for the Rubrik Cluster # -######################################### - -resource "aws_security_group" "rubrik_cloud_cluster" { - name = var.aws_vpc_security_group_name_cloud_cluster_nodes - description = "Allow hosts to talk to Rubrik Cloud Cluster" - vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id - tags = merge( - var.aws_tags, - { "sg:purpose" = "rubrik-cluster-to-self" } - ) - - lifecycle { - create_before_destroy = true - } +locals { + aws_key_pair_name = var.aws_key_pair_name == "" ? module.aws_key_pair.key_pair_key_name : var.aws_key_pair_name } -resource "aws_security_group_rule" "rubrik_cloud_cluster_node_ingress" { - type = "ingress" - description = "Intra cluster communication" - from_port = 0 - to_port = 0 - protocol = "-1" - self = true - security_group_id = aws_security_group.rubrik_cloud_cluster.id -} +######################################## +# S3 VPC Endpoint for Cloud Cluster ES # +######################################## -resource "aws_security_group_rule" "rubrik_cloud_cluster_node_egress" { - type = "egress" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - ipv6_cidr_blocks = ["::/0"] - security_group_id = aws_security_group.rubrik_cloud_cluster.id -} +module "s3_vpc_endpoint" { + source = "./modules/s3_vpc_endpoint" -resource "aws_security_group_rule" "rubrik_cloud_cluster_cli_admin" { - type = "ingress" - description = "CLI administration of the nodes" - from_port = 22 - to_port = 22 - protocol = "tcp" - security_group_id = aws_security_group.rubrik_cloud_cluster.id - source_security_group_id = aws_security_group.rubrik_hosts.id + create = var.create_s3_vpc_endpoint + vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id + #route_table_ids = [data.aws_vpc.rubrik_cloud_cluster.main_route_table_id] + #endpoint_name = (var.s3_vpc_endpoint_name == "" ? "${local.cluster_name}.vpc-ep" : var.s3_vpc_endpoint_name) + tags = merge( + var.aws_tags + ) } -resource "aws_security_group_rule" "rubrik_cloud_cluster_web_admin" { - type = "ingress" - description = "Web administration of the nodes" - from_port = 443 - to_port = 443 - protocol = "tcp" - security_group_id = aws_security_group.rubrik_cloud_cluster.id - source_security_group_id = aws_security_group.rubrik_hosts.id -} +###################################################################### +# Create, then configure, the Security Groups for the Rubrik Cluster # +###################################################################### +module "rubrik_nodes_sg" { + source = "terraform-aws-modules/security-group/aws" -resource "aws_security_group" "rubrik_hosts" { - name = var.aws_vpc_security_group_name_cloud_cluster_hosts - description = "Allow Rubrik Cloud Cluster to communicate with hosts" + use_name_prefix = true + name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${local.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name + description = "Allow hosts to talk to Rubrik Cloud Cluster and Cluster to talk to itself" vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id + create = var.create_aws_rubrik_hosts_sg tags = merge( - var.aws_tags, - { "sg:purpose" = "rubrik-cluster-to-self" } + {name = "${local.cluster_tag}:sg"}, + var.aws_tags ) - - lifecycle { - create_before_destroy = true - } } -resource "aws_security_group_rule" "rubrik_cloud_cluster_rbs" { - type = "ingress" - description = "Ports for Rubrik Backup Service (RBS)" - from_port = 12800 - to_port = 12801 - protocol = "tcp" - security_group_id = aws_security_group.rubrik_hosts.id - source_security_group_id = aws_security_group.rubrik_cloud_cluster.id +module "rubrik_nodes_sg_rules" { + source = "./modules/rubrik_nodes_sg" + sg_id = module.rubrik_nodes_sg.security_group_id + rubrik_hosts_sg_id = module.rubrik_hosts_sg.security_group_id + create = var.create_aws_rubrik_hosts_sg + tags = merge( + {name = "${local.cluster_tag}:sg-rule"}, + var.aws_tags + ) + depends_on = [ + module.rubrik_hosts_sg + ] } -############################### -# Create EC2 Instances in AWS # -############################### +module "rubrik_hosts_sg" { + source = "terraform-aws-modules/security-group/aws" -resource "aws_instance" "rubrik_cluster" { - for_each = toset(local.cluster_node_names) - instance_type = var.aws_instance_type - ami = data.aws_ami_ids.rubrik_cloud_cluster.ids[0] - vpc_security_group_ids = concat([ - aws_security_group.rubrik_cloud_cluster.id - ], var.aws_security_group_ids) - subnet_id = var.aws_subnet_id - key_name = aws_key_pair.rubrik_cloud_cluster.key_name - - tags = merge({ - Name = each.value }, + use_name_prefix = true + name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${local.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name + description = "Allow Rubrik Cloud Cluster to talk to hosts, and hosts with this security group can talk to cluster" + vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id + create = var.create_aws_rubrik_hosts_sg + tags = merge( + {name = "${local.cluster_tag}:sg"}, var.aws_tags ) - - disable_api_termination = var.aws_disable_api_termination - iam_instance_profile = var.aws_iam_instance_profile - root_block_device { - encrypted = true - } - } -resource "aws_ebs_volume" "ebs_block_device" { - for_each = local.cluster_disks - availability_zone = data.aws_subnet.rubrik_cloud_cluster.availability_zone - type = var.cluster_disk_type - size = var.cluster_disk_size +module "rubrik_hosts_sg_rules" { + source = "./modules/rubrik_hosts_sg" + + sg_id = module.rubrik_hosts_sg.security_group_id + rubrik_nodes_sg_id = module.rubrik_nodes_sg.security_group_id + create = var.create_aws_rubrik_hosts_sg tags = merge( - {Name = each.key}, + {name = "${local.cluster_tag}:sg-rule"}, var.aws_tags ) - encrypted = true + depends_on = [ + module.rubrik_nodes_sg + ] +} + + +########################### +# Create S3 Bucket in AWS # +########################### +module "s3_bucket" { + source = "terraform-aws-modules/s3-bucket/aws" + + bucket = (var.s3_bucket_name == "" ? "${local.cluster_name}.bucket-DO-NOT-DELETE" : var.s3_bucket_name) + acl = "private" } -resource "aws_volume_attachment" "ebs_att" { - for_each = local.cluster_disks - device_name = each.value.device - volume_id = aws_ebs_volume.ebs_block_device[each.key].id - instance_id = aws_instance.rubrik_cluster[each.value.instance].id +############################## +# Create IAM Role and Policy # +############################## +module "iam_role" { + source = "./modules/iam_role" + + bucket = module.s3_bucket.s3_bucket_id + create = var.create_iam_role + role_name = "thingy" + role_policy_name = "thingy-pol" + instance_profile_name = "thingy-profile" +} + +############################### +# Create EC2 Instances in AWS # +############################### + +module "cluster_nodes" { + source = "./modules/rubrik_aws_instances" + + node_names = local.cluster_node_names + node_config = local.cluster_node_config + disks = local.cluster_disks } \ No newline at end of file diff --git a/modules/iam_role/main.tf b/modules/iam_role/main.tf new file mode 100644 index 0000000..947893d --- /dev/null +++ b/modules/iam_role/main.tf @@ -0,0 +1,77 @@ +variable "bucket" { + type = string +} + +variable "create" { + type = bool + default = true +} + +variable "role_name" { + type = string +} + +variable "role_policy_name" { + type = string +} + +variable "instance_profile_name" { + type = string +} + +variable "tags" { + type = map(string) + default = { } +} + +data "template_file" "aws_iam_role_policy" { + template = file("cc_es_policy.json.tpl") + vars = { + resource = var.bucket + } +} + +resource "aws_iam_role" "rubrik_ec2_s3" { + count = var.create ? 1 : 0 + + name = var.role_name + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Sid = "" + Principal = { + Service = "ec2.amazonaws.com" + } + }, + ] + }) + + tags = var.tags +} + +resource "aws_iam_role_policy" "rubrik_ec2_s3_policy" { + count = var.create ? 1 : 0 + name = var.role_policy_name + role = aws_iam_role.rubrik_ec2_s3[0].name + policy = data.template_file.aws_iam_role_policy.rendered +} + +resource "aws_iam_instance_profile" "rubrik_ec2_s3_profile" { + count = var.create ? 1 : 0 + name = var.instance_profile_name + role = aws_iam_role.rubrik_ec2_s3[0].name + + tags = var.tags +} + +data "aws_iam_instance_profile" "rubrik_ec2_s3_profile" { + name = var.instance_profile_name + depends_on = [aws_iam_instance_profile.rubrik_ec2_s3_profile] +} + +output "aws_iam_instance_profile" { + value = data.aws_iam_instance_profile.rubrik_ec2_s3_profile +} \ No newline at end of file diff --git a/modules/rubrik_aws_instances/main.tf b/modules/rubrik_aws_instances/main.tf new file mode 100644 index 0000000..9d46668 --- /dev/null +++ b/modules/rubrik_aws_instances/main.tf @@ -0,0 +1,65 @@ +variable "node_names" { + type = set(string) +} + +variable "node_config" { + type = object({ + instance_type = string + ami_id = string + sg_ids = set(string) + subnet_id = string + key_pair_name = string + disable_api_termination = bool + iam_instance_profile = string + availability_zone = string + tags = map(string) + }) +} + +variable "disks" { + type = map(string) +} + +resource "aws_instance" "rubrik_cluster" { + for_each = var.node_names + instance_type = var.node_config.instance_type + ami = var.node_config.ami_id + vpc_security_group_ids = var.node_config.sg_ids + subnet_id = var.node_config.subnet_id + key_name = var.node_config.key_pair_name + + tags = merge({ + Name = each.value }, + var.node_config.tags + ) + + disable_api_termination = var.node_config.disable_api_termination + iam_instance_profile = var.node_config.iam_instance_profile + root_block_device { + encrypted = true + } + +} + +resource "aws_ebs_volume" "ebs_block_device" { + for_each = var.disks + availability_zone = var.node_config.availability_zone + type = each.value.type + size = each.value.size + tags = merge( + {Name = each.key}, + var.node_config.tags + ) + encrypted = true +} + +resource "aws_volume_attachment" "ebs_att" { + for_each = var.disks + device_name = each.value.device + volume_id = aws_ebs_volume.ebs_block_device[each.key].id + instance_id = aws_instance.rubrik_cluster[each.value.instance].id +} + +output "instances" { + value = aws_instance.rubrik_cluster +} \ No newline at end of file diff --git a/modules/rubrik_hosts_sg/main.tf b/modules/rubrik_hosts_sg/main.tf new file mode 100644 index 0000000..94ca8af --- /dev/null +++ b/modules/rubrik_hosts_sg/main.tf @@ -0,0 +1,22 @@ +module "this" { + source = "terraform-aws-modules/security-group/aws" + + create_sg = false + security_group_id = var.sg_id + create = var.create + + ingress_with_source_security_group_id = [ + { + from_port = 12800 + to_port = 12801 + protocol = "tcp" + description = "Ports for Rubrik Backup Service (RBS)" + source_security_group_id = var.rubrik_nodes_sg_id + }, + ] + + tags = merge( + var.tags, + { "sg:purpose" = "rubrik-cluster-to-self" } + ) +} \ No newline at end of file diff --git a/modules/rubrik_hosts_sg/variables.tf b/modules/rubrik_hosts_sg/variables.tf new file mode 100644 index 0000000..b0b3d14 --- /dev/null +++ b/modules/rubrik_hosts_sg/variables.tf @@ -0,0 +1,17 @@ +variable "sg_id" { + type = string +} + +variable "create" { + type = bool + default = true +} + +variable "tags" { + type = map(string) + default = { } +} + +variable "rubrik_nodes_sg_id" { + type = string +} \ No newline at end of file diff --git a/modules/rubrik_nodes_sg/main.tf b/modules/rubrik_nodes_sg/main.tf new file mode 100644 index 0000000..09f688e --- /dev/null +++ b/modules/rubrik_nodes_sg/main.tf @@ -0,0 +1,48 @@ +module "this" { + source = "terraform-aws-modules/security-group/aws" + + create_sg = false + security_group_id = var.sg_id + create = var.create + + ingress_with_self = [{ rule = "all-all" }] + egress_rules = ["all-all"] + ingress_with_source_security_group_id = [ + { description = "HTTPS over TCP" + from_port = 443 + to_port = 443 + protocol = "tcp" + source_security_group_id = var.rubrik_hosts_sg_id + }, + { description = "SSH over TCP" + from_port = 22 + to_port = 22 + protocol = "tcp" + source_security_group_id = var.rubrik_hosts_sg_id + }, + { description = "NFS over TCP" + from_port = 2049 + to_port = 2049 + protocol = "tcp" + source_security_group_id = var.rubrik_hosts_sg_id + }, + { description = "SMB over TCP" + from_port = 445 + to_port = 445 + protocol = "tcp" + source_security_group_id = var.rubrik_hosts_sg_id + }, + { description = "SMB over TCP/UDP via NetBIOS" + from_port = 137 + to_port = 139 + protocol = -1 + source_security_group_id = var.rubrik_hosts_sg_id + } + + ] + + tags = merge( + var.tags, + { "sg:purpose" = "rubrik-cluster-to-self" } + ) +} \ No newline at end of file diff --git a/modules/rubrik_nodes_sg/variables.tf b/modules/rubrik_nodes_sg/variables.tf new file mode 100644 index 0000000..6ed7ee7 --- /dev/null +++ b/modules/rubrik_nodes_sg/variables.tf @@ -0,0 +1,17 @@ +variable "sg_id" { + type = string +} + +variable "create" { + type = bool + default = true +} + +variable "tags" { + type = map(string) + default = {} +} + +variable "rubrik_hosts_sg_id" { + type = string +} \ No newline at end of file diff --git a/modules/s3_vpc_endpoint/main.tf b/modules/s3_vpc_endpoint/main.tf new file mode 100644 index 0000000..71d0b61 --- /dev/null +++ b/modules/s3_vpc_endpoint/main.tf @@ -0,0 +1,30 @@ +data "aws_region" "current" {} + +module "endpoints" { + source = "terraform-aws-modules/vpc/aws//modules/vpc-endpoints" + + vpc_id = var.vpc_id + create = var.create + + endpoints = { + s3 = { + # interface endpoint + service = "s3" + tags = var.tags + route_table_ids = var.route_table_ids + + } + } + + tags = merge( + var.tags, + ) +} + +data "aws_vpc_endpoint" "this" { + vpc_id = var.vpc_id + service_name = "com.amazonaws.${data.aws_region.current.name}.s3" + depends_on = [ + module.endpoints + ] +} \ No newline at end of file diff --git a/modules/s3_vpc_endpoint/output.tf b/modules/s3_vpc_endpoint/output.tf new file mode 100644 index 0000000..afede69 --- /dev/null +++ b/modules/s3_vpc_endpoint/output.tf @@ -0,0 +1,4 @@ +output "endpoint" { + description = "Array containing the full resource object and attributes for all endpoints created" + value = data.aws_vpc_endpoint.this +} \ No newline at end of file diff --git a/modules/s3_vpc_endpoint/variables.tf b/modules/s3_vpc_endpoint/variables.tf new file mode 100644 index 0000000..c5c214d --- /dev/null +++ b/modules/s3_vpc_endpoint/variables.tf @@ -0,0 +1,22 @@ +variable "create" { + default = true +} + +variable "vpc_id" { + type = string +} + +variable "route_table_ids" { + type = list(string) + default = null +} + +variable "tags" { + type = map(string) + default = { Name = "s3-vpc-endpoint" } +} + +variable "endpoint_name" { + type = string + default = null +} \ No newline at end of file diff --git a/output.tf b/output.tf index c3469a9..7540ea1 100644 --- a/output.tf +++ b/output.tf @@ -2,6 +2,10 @@ output "rubrik_cloud_cluster_ip_addrs" { value = local.cluster_node_ips } -output "rubrik_protected_hosts_security_group_id" { - value = aws_security_group.rubrik_hosts.id +output "rubrik_hosts_sg_id" { + value = module.rubrik_hosts_sg.security_group_id +} + +output "s3_bucket" { + value = module.s3_bucket.s3_bucket_id } \ No newline at end of file diff --git a/variables.tf b/variables.tf index 812ba72..0082a96 100644 --- a/variables.tf +++ b/variables.tf @@ -1,47 +1,48 @@ variable "aws_region" { description = "The region to deploy Rubrik Cloud Cluster nodes." -} + } + variable "aws_instance_type" { description = "The type of instance to use as Rubrik Cloud Cluster nodes." default = "m5.4xlarge" -} + } variable "aws_disable_api_termination" { description = "If true, enables EC2 Instance Termination Protection on the Rubrik Cloud Cluster nodes." default = true -} + } -variable "aws_vpc_security_group_name_cloud_cluster_nodes" { +variable "aws_vpc_cloud_cluster_nodes_sg_name" { description = "The name of the security group to create for Rubrik Cloud Cluster to use." default = "Rubrik Cloud Cluster" -} + } -variable "aws_vpc_security_group_name_cloud_cluster_hosts" { +variable "aws_vpc_cloud_cluster_hosts_sg_name" { description = "The name of the security group to create for Rubrik Cloud Cluster to communicate with EC2 instances." default = "Rubrik Cloud Cluster Hosts" -} + } -variable "aws_security_group_ids" { +variable "aws_cloud_cluster_nodes_sg_ids" { description = "Extra security groups to add to Rubrik cluster nodes" type = list(string) default = [] -} + } variable "aws_iam_instance_profile" { description = "IAM instance profile for accessing S3 with Cloud Cluster ES" type = string default = "" -} + } variable "aws_tags" { description = "Extra tags to add to Rubrik cluster nodes" type = map(string) default = {} -} + } variable "aws_subnet_id" { description = "The VPC Subnet ID to launch Rubrik Cloud Cluster in." -} + } variable "aws_public_key" { description = "The public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster." @@ -86,11 +87,13 @@ variable "admin_password" { variable "dns_search_domain" { type = list(any) description = "List of search domains that the DNS Service will use to resolve hostnames that are not fully qualified." + default = [] } variable "dns_name_servers" { type = list(any) description = "List of the IPv4 addresses of the DNS servers." + default = ["169.254.169.253"] } variable "ntp_servers" { @@ -113,4 +116,58 @@ variable "aws_ami_filter" { description = "Set of AWS AMI names to search for" type = set(string) default = ["rubrik-mp-cc-*"] +} + +variable "environment_tag" { + description = "Prefix used to identify an environment for tagging like \"prod\" or \"europe:shared:dev\"" + type = string + default = "" +} + +variable "environment" { + description = "Prefix used to identify an environment for to be added to names like \"prod\" or \"europe-shared-dev\"" + type = string + default = "" +} + +variable "aws_key_pair_name" { + description = "Name used to identify a new or existing AWS SSH Key-Pair" + type = string + default = "" +} + +variable "create_key_pair" { + description = "Should a new AWS SSH Key-Pair be created?" + type = bool + default = true +} + +variable "create_aws_rubrik_nodes_sg" { + description = "Should a new Security Group be created for node to node traffic within the Rubrik cluster?" + type = bool + default = true +} + +variable "create_aws_rubrik_hosts_sg" { + description = "Should a new Security Group be created for node to host traffic from the Rubrik cluster?" + type = bool + default = true +} + +variable "create_iam_role" { + description = "Should the required IAM role, role policy, and instance profile be created?" + type = bool + default = true +} + +variable "create_s3_vpc_endpoint" { + description = "Should the required VPC Endpoint and S3 Endpoint Service be created?" + type = bool + default = true +} + +variable "s3_bucket_name" { + description = "Optional name to assign the S3 bucket" + type = string + default = "" } \ No newline at end of file From 2f2fb24c04a1a81c9973a33adbe4c7eea31495b3 Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Sun, 11 Jul 2021 07:29:39 -0500 Subject: [PATCH 06/28] fix s3 gateway and bucket name --- main.tf | 4 ++-- modules/s3_vpc_endpoint/main.tf | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/main.tf b/main.tf index b6dc7ff..a495b59 100644 --- a/main.tf +++ b/main.tf @@ -3,7 +3,7 @@ ############################# locals { cluster_name = var.environment == "" ? var.cluster_name : "${var.environment}.${var.cluster_name}" - cluster_node_names = formatlist("${local.cluster_name}-%01s", range(1, var.number_of_nodes + 1)) + cluster_node_names = formatlist("${local.cluster_name}-%02s", range(1, var.number_of_nodes + 1)) cluster_node_config = { "instance_type" = var.aws_instance_type, "ami_id" = data.aws_ami_ids.rubrik_cloud_cluster.ids[0], @@ -145,7 +145,7 @@ module "rubrik_hosts_sg_rules" { module "s3_bucket" { source = "terraform-aws-modules/s3-bucket/aws" - bucket = (var.s3_bucket_name == "" ? "${local.cluster_name}.bucket-DO-NOT-DELETE" : var.s3_bucket_name) + bucket = (var.s3_bucket_name == "" ? "${local.cluster_name}.bucket-do-not-delete" : var.s3_bucket_name) acl = "private" } diff --git a/modules/s3_vpc_endpoint/main.tf b/modules/s3_vpc_endpoint/main.tf index 71d0b61..e999dbe 100644 --- a/modules/s3_vpc_endpoint/main.tf +++ b/modules/s3_vpc_endpoint/main.tf @@ -8,10 +8,11 @@ module "endpoints" { endpoints = { s3 = { - # interface endpoint + # gateway endpoint service = "s3" tags = var.tags route_table_ids = var.route_table_ids + vpc_endpoint_type = "Gateway" } } From 7100d8fb3e64e2f491ebbbd5196ace247462e041 Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Sun, 11 Jul 2021 07:38:15 -0500 Subject: [PATCH 07/28] fix s3 endpoint --- modules/s3_vpc_endpoint/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/s3_vpc_endpoint/main.tf b/modules/s3_vpc_endpoint/main.tf index e999dbe..2de37d4 100644 --- a/modules/s3_vpc_endpoint/main.tf +++ b/modules/s3_vpc_endpoint/main.tf @@ -12,7 +12,7 @@ module "endpoints" { service = "s3" tags = var.tags route_table_ids = var.route_table_ids - vpc_endpoint_type = "Gateway" + service_type = "Gateway" } } From 0aa2c90e280fdfdcf91262231210cdfa8905b9ea Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Sun, 11 Jul 2021 11:22:58 -0500 Subject: [PATCH 08/28] fix "thingy" reference --- main.tf | 6 +++--- variables.tf | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/main.tf b/main.tf index a495b59..033c9df 100644 --- a/main.tf +++ b/main.tf @@ -157,9 +157,9 @@ module "iam_role" { bucket = module.s3_bucket.s3_bucket_id create = var.create_iam_role - role_name = "thingy" - role_policy_name = "thingy-pol" - instance_profile_name = "thingy-profile" + role_name = var.aws_cloud_cluster_iam_role_name == "" ? "${local.cluster_name}.role" : var.aws_cloud_cluster_iam_role_name + role_policy_name = var.aws_cloud_cluster_iam_role_policy_name == "" ? "${local.cluster_name}.role-policy" : var.aws_cloud_cluster_iam_role_policy_name + instance_profile_name = var.aws_cloud_cluster_ec2_instance_profile_name == "" ? "${local.cluster_name}.instance-profile" : var.aws_cloud_cluster_ec2_instance_profile_name } ############################### diff --git a/variables.tf b/variables.tf index 0082a96..6c70c5a 100644 --- a/variables.tf +++ b/variables.tf @@ -170,4 +170,23 @@ variable "s3_bucket_name" { description = "Optional name to assign the S3 bucket" type = string default = "" -} \ No newline at end of file +} + +variable "aws_cloud_cluster_iam_role_name" { + description = "Optional name to assign to the AWS IAM Role that is used to access S3" + type = string + default = "" +} + +variable "aws_cloud_cluster_iam_role_policy_name" { + description = "Optional name to assign to the AWS IAM Role policy that is used to access S3" + type = string + default = "" +} + +variable "aws_cloud_cluster_ec2_instance_profile_name" { + description = "Optional name to assign to the AWS EC2 Instance Profile that links the IAM Role to the cluster" + type = string + default = "" +} + From 0799976e3d35b7178c56feb68a7c2ff119c56fab Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Thu, 22 Jul 2021 16:37:44 -0700 Subject: [PATCH 09/28] fmt fixes --- main.tf | 88 ++++++++++++++++++++++++++-------------------------- variables.tf | 68 ++++++++++++++++++++-------------------- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/main.tf b/main.tf index 033c9df..268326a 100644 --- a/main.tf +++ b/main.tf @@ -2,28 +2,28 @@ # Dynamic Variable Creation # ############################# locals { - cluster_name = var.environment == "" ? var.cluster_name : "${var.environment}.${var.cluster_name}" + cluster_name = var.environment == "" ? var.cluster_name : "${var.environment}.${var.cluster_name}" cluster_node_names = formatlist("${local.cluster_name}-%02s", range(1, var.number_of_nodes + 1)) cluster_node_config = { - "instance_type" = var.aws_instance_type, - "ami_id" = data.aws_ami_ids.rubrik_cloud_cluster.ids[0], - "sg_ids" = concat(var.aws_cloud_cluster_nodes_sg_ids, [module.rubrik_nodes_sg.security_group_id]), - "subnet_id" = var.aws_subnet_id, - "key_pair_name" = local.aws_key_pair_name, + "instance_type" = var.aws_instance_type, + "ami_id" = data.aws_ami_ids.rubrik_cloud_cluster.ids[0], + "sg_ids" = concat(var.aws_cloud_cluster_nodes_sg_ids, [module.rubrik_nodes_sg.security_group_id]), + "subnet_id" = var.aws_subnet_id, + "key_pair_name" = local.aws_key_pair_name, "disable_api_termination" = var.aws_disable_api_termination, - "iam_instance_profile" = module.iam_role.aws_iam_instance_profile.name, - "availability_zone" = data.aws_subnet.rubrik_cloud_cluster.availability_zone, - "tags" = var.aws_tags + "iam_instance_profile" = module.iam_role.aws_iam_instance_profile.name, + "availability_zone" = data.aws_subnet.rubrik_cloud_cluster.availability_zone, + "tags" = var.aws_tags } - cluster_node_ips = [for i in module.cluster_nodes.instances: i.private_ip] + cluster_node_ips = [for i in module.cluster_nodes.instances : i.private_ip] cluster_disks = { - for v in setproduct(local.cluster_node_names,range(var.cluster_disk_count)) : - "${v[0]}-sd${substr("bcdefghi", v[1], 1)}" => { - "instance" = v[0], - "device" = "/dev/sd${substr("bcdefghi", v[1], 1)}" - "size" = var.cluster_disk_size - "type" = var.cluster_disk_type - } + for v in setproduct(local.cluster_node_names, range(var.cluster_disk_count)) : + "${v[0]}-sd${substr("bcdefghi", v[1], 1)}" => { + "instance" = v[0], + "device" = "/dev/sd${substr("bcdefghi", v[1], 1)}" + "size" = var.cluster_disk_size + "type" = var.cluster_disk_type + } } cluster_tag = var.environment_tag == "" ? local.cluster_name : "${var.environment_tag}:${local.cluster_name}" } @@ -52,8 +52,8 @@ data "aws_ami_ids" "rubrik_cloud_cluster" { module "aws_key_pair" { source = "terraform-aws-modules/key-pair/aws" - key_name = var.aws_key_pair_name == "" ? "${local.cluster_name}.key-pair" : var.aws_key_pair_name - public_key = var.aws_public_key + key_name = var.aws_key_pair_name == "" ? "${local.cluster_name}.key-pair" : var.aws_key_pair_name + public_key = var.aws_public_key create_key_pair = var.create_key_pair } @@ -85,23 +85,23 @@ module "rubrik_nodes_sg" { source = "terraform-aws-modules/security-group/aws" use_name_prefix = true - name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${local.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name - description = "Allow hosts to talk to Rubrik Cloud Cluster and Cluster to talk to itself" - vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id - create = var.create_aws_rubrik_hosts_sg + name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${local.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name + description = "Allow hosts to talk to Rubrik Cloud Cluster and Cluster to talk to itself" + vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id + create = var.create_aws_rubrik_hosts_sg tags = merge( - {name = "${local.cluster_tag}:sg"}, + { name = "${local.cluster_tag}:sg" }, var.aws_tags ) } module "rubrik_nodes_sg_rules" { - source = "./modules/rubrik_nodes_sg" - sg_id = module.rubrik_nodes_sg.security_group_id + source = "./modules/rubrik_nodes_sg" + sg_id = module.rubrik_nodes_sg.security_group_id rubrik_hosts_sg_id = module.rubrik_hosts_sg.security_group_id - create = var.create_aws_rubrik_hosts_sg + create = var.create_aws_rubrik_hosts_sg tags = merge( - {name = "${local.cluster_tag}:sg-rule"}, + { name = "${local.cluster_tag}:sg-rule" }, var.aws_tags ) depends_on = [ @@ -113,12 +113,12 @@ module "rubrik_hosts_sg" { source = "terraform-aws-modules/security-group/aws" use_name_prefix = true - name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${local.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name - description = "Allow Rubrik Cloud Cluster to talk to hosts, and hosts with this security group can talk to cluster" - vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id - create = var.create_aws_rubrik_hosts_sg + name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${local.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name + description = "Allow Rubrik Cloud Cluster to talk to hosts, and hosts with this security group can talk to cluster" + vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id + create = var.create_aws_rubrik_hosts_sg tags = merge( - {name = "${local.cluster_tag}:sg"}, + { name = "${local.cluster_tag}:sg" }, var.aws_tags ) } @@ -126,11 +126,11 @@ module "rubrik_hosts_sg" { module "rubrik_hosts_sg_rules" { source = "./modules/rubrik_hosts_sg" - sg_id = module.rubrik_hosts_sg.security_group_id + sg_id = module.rubrik_hosts_sg.security_group_id rubrik_nodes_sg_id = module.rubrik_nodes_sg.security_group_id - create = var.create_aws_rubrik_hosts_sg + create = var.create_aws_rubrik_hosts_sg tags = merge( - {name = "${local.cluster_tag}:sg-rule"}, + { name = "${local.cluster_tag}:sg-rule" }, var.aws_tags ) depends_on = [ @@ -155,12 +155,12 @@ module "s3_bucket" { module "iam_role" { source = "./modules/iam_role" - bucket = module.s3_bucket.s3_bucket_id - create = var.create_iam_role - role_name = var.aws_cloud_cluster_iam_role_name == "" ? "${local.cluster_name}.role" : var.aws_cloud_cluster_iam_role_name - role_policy_name = var.aws_cloud_cluster_iam_role_policy_name == "" ? "${local.cluster_name}.role-policy" : var.aws_cloud_cluster_iam_role_policy_name + bucket = module.s3_bucket.s3_bucket_id + create = var.create_iam_role + role_name = var.aws_cloud_cluster_iam_role_name == "" ? "${local.cluster_name}.role" : var.aws_cloud_cluster_iam_role_name + role_policy_name = var.aws_cloud_cluster_iam_role_policy_name == "" ? "${local.cluster_name}.role-policy" : var.aws_cloud_cluster_iam_role_policy_name instance_profile_name = var.aws_cloud_cluster_ec2_instance_profile_name == "" ? "${local.cluster_name}.instance-profile" : var.aws_cloud_cluster_ec2_instance_profile_name -} +} ############################### # Create EC2 Instances in AWS # @@ -168,8 +168,8 @@ module "iam_role" { module "cluster_nodes" { source = "./modules/rubrik_aws_instances" - - node_names = local.cluster_node_names + + node_names = local.cluster_node_names node_config = local.cluster_node_config - disks = local.cluster_disks + disks = local.cluster_disks } \ No newline at end of file diff --git a/variables.tf b/variables.tf index 6c70c5a..a69cc3e 100644 --- a/variables.tf +++ b/variables.tf @@ -1,48 +1,48 @@ variable "aws_region" { description = "The region to deploy Rubrik Cloud Cluster nodes." - } +} variable "aws_instance_type" { description = "The type of instance to use as Rubrik Cloud Cluster nodes." default = "m5.4xlarge" - } +} variable "aws_disable_api_termination" { description = "If true, enables EC2 Instance Termination Protection on the Rubrik Cloud Cluster nodes." default = true - } +} variable "aws_vpc_cloud_cluster_nodes_sg_name" { description = "The name of the security group to create for Rubrik Cloud Cluster to use." default = "Rubrik Cloud Cluster" - } +} variable "aws_vpc_cloud_cluster_hosts_sg_name" { description = "The name of the security group to create for Rubrik Cloud Cluster to communicate with EC2 instances." default = "Rubrik Cloud Cluster Hosts" - } +} variable "aws_cloud_cluster_nodes_sg_ids" { description = "Extra security groups to add to Rubrik cluster nodes" type = list(string) default = [] - } +} variable "aws_iam_instance_profile" { description = "IAM instance profile for accessing S3 with Cloud Cluster ES" type = string default = "" - } +} variable "aws_tags" { description = "Extra tags to add to Rubrik cluster nodes" type = map(string) default = {} - } +} variable "aws_subnet_id" { description = "The VPC Subnet ID to launch Rubrik Cloud Cluster in." - } +} variable "aws_public_key" { description = "The public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster." @@ -120,73 +120,73 @@ variable "aws_ami_filter" { variable "environment_tag" { description = "Prefix used to identify an environment for tagging like \"prod\" or \"europe:shared:dev\"" - type = string - default = "" + type = string + default = "" } variable "environment" { description = "Prefix used to identify an environment for to be added to names like \"prod\" or \"europe-shared-dev\"" - type = string - default = "" + type = string + default = "" } -variable "aws_key_pair_name" { +variable "aws_key_pair_name" { description = "Name used to identify a new or existing AWS SSH Key-Pair" - type = string - default = "" + type = string + default = "" } variable "create_key_pair" { description = "Should a new AWS SSH Key-Pair be created?" - type = bool - default = true + type = bool + default = true } variable "create_aws_rubrik_nodes_sg" { description = "Should a new Security Group be created for node to node traffic within the Rubrik cluster?" - type = bool - default = true + type = bool + default = true } variable "create_aws_rubrik_hosts_sg" { description = "Should a new Security Group be created for node to host traffic from the Rubrik cluster?" - type = bool - default = true + type = bool + default = true } variable "create_iam_role" { description = "Should the required IAM role, role policy, and instance profile be created?" - type = bool - default = true + type = bool + default = true } variable "create_s3_vpc_endpoint" { description = "Should the required VPC Endpoint and S3 Endpoint Service be created?" - type = bool - default = true + type = bool + default = true } variable "s3_bucket_name" { description = "Optional name to assign the S3 bucket" - type = string - default = "" + type = string + default = "" } variable "aws_cloud_cluster_iam_role_name" { description = "Optional name to assign to the AWS IAM Role that is used to access S3" - type = string - default = "" + type = string + default = "" } variable "aws_cloud_cluster_iam_role_policy_name" { description = "Optional name to assign to the AWS IAM Role policy that is used to access S3" - type = string - default = "" + type = string + default = "" } variable "aws_cloud_cluster_ec2_instance_profile_name" { description = "Optional name to assign to the AWS EC2 Instance Profile that links the IAM Role to the cluster" - type = string - default = "" + type = string + default = "" } From b615064d9eabbcdd0092b618898dc15bdf65f5f8 Mon Sep 17 00:00:00 2001 From: Rich Brumpton Date: Tue, 27 Jul 2021 13:18:50 -0500 Subject: [PATCH 10/28] fixes for non-ES clusters --- main.tf | 1 + modules/rubrik_aws_instances/main.tf | 2 +- variables.tf | 12 +++++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/main.tf b/main.tf index 268326a..269392a 100644 --- a/main.tf +++ b/main.tf @@ -145,6 +145,7 @@ module "rubrik_hosts_sg_rules" { module "s3_bucket" { source = "terraform-aws-modules/s3-bucket/aws" + create_bucket = var.create_s3_bucket bucket = (var.s3_bucket_name == "" ? "${local.cluster_name}.bucket-do-not-delete" : var.s3_bucket_name) acl = "private" } diff --git a/modules/rubrik_aws_instances/main.tf b/modules/rubrik_aws_instances/main.tf index 9d46668..20c8974 100644 --- a/modules/rubrik_aws_instances/main.tf +++ b/modules/rubrik_aws_instances/main.tf @@ -17,7 +17,7 @@ variable "node_config" { } variable "disks" { - type = map(string) + type = map(any) } resource "aws_instance" "rubrik_cluster" { diff --git a/variables.tf b/variables.tf index a69cc3e..699a413 100644 --- a/variables.tf +++ b/variables.tf @@ -65,7 +65,7 @@ variable "cluster_disk_size" { } variable "cluster_disk_count" { - description = "The number of disks for each node in the cluster. Set to 0 to use with S3 storage for Cloud Cluster ES" + description = "The number of disks for each node in the cluster. Set to 1 to use with S3 storage for Cloud Cluster ES" type = number default = 4 } @@ -161,9 +161,15 @@ variable "create_iam_role" { } variable "create_s3_vpc_endpoint" { - description = "Should the required VPC Endpoint and S3 Endpoint Service be created?" + description = "Should the required VPC Endpoint and S3 Endpoint Service for Cloud Cluster ES be created?" type = bool - default = true + default = false +} + +variable "create_s3_bucket" { + description = "Should the required S3 bucket for Cloud Cluster ES be created?" + type = bool + default = false } variable "s3_bucket_name" { From a0a458d3cb4fcbcdf2ee3e1d9a89161b9fd6402d Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:01:05 -0700 Subject: [PATCH 11/28] Added support for creating SSH key pair --- README.md | 6 ++---- docs/quick-start.md | 6 ++---- main.tf | 16 +++++++++++++++- output.tf | 4 ++++ variables.tf | 14 ++++++++------ 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 4c1d0a0..5602ed9 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,8 @@ The following are the variables accepted by the module. | Name | Description | Type | Default | Required | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | | aws_region | The region to deploy Rubrik Cloud Cluster nodes. | string | | yes | -| aws_instance_type | The type of instance to use as Rubrik Cloud Cluster nodes. | string | m5.xlarge | no | -| aws_disable_api_termination | If true, enables EC2 Instance Termination Protection | bool | true | no | -| aws_vpc_security_group_name_cloud_cluster_nodes | The name of the security group to create for Rubrik Cloud Cluster to use. | string | Rubrik Cloud Cluster | yes | -| aws_vpc_security_group_name_cloud_cluster_hosts | The name of the security group to create for Rubrik Cloud Cluster to communicate with EC2 instances. | string | Rubrik Cloud Cluster Hosts | yes | +| create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | +| aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | | aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | | number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 4 | no | diff --git a/docs/quick-start.md b/docs/quick-start.md index a122ac7..3b1ec42 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -28,10 +28,8 @@ The following are the variables accepted by the module. | Name | Description | Type | Default | Required | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | | aws_region | The region to deploy Rubrik Cloud Cluster nodes. | string | | yes | -| aws_instance_type | The type of instance to use as Rubrik Cloud Cluster nodes. | string | m5.xlarge | no | -| aws_disable_api_termination | If true, enables EC2 Instance Termination Protection | bool | true | no | -| aws_vpc_security_group_name_cloud_cluster_nodes | The name of the security group to create for Rubrik Cloud Cluster to use. | string | Rubrik Cloud Cluster | yes | -| aws_vpc_security_group_name_cloud_cluster_hosts | The name of the security group to create for Rubrik Cloud Cluster to communicate with EC2 instances. | string | Rubrik Cloud Cluster Hosts | yes | +| create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | +| aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | | aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | | number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 4 | no | diff --git a/main.tf b/main.tf index 269392a..1cd31fe 100644 --- a/main.tf +++ b/main.tf @@ -25,7 +25,21 @@ locals { "type" = var.cluster_disk_type } } - cluster_tag = var.environment_tag == "" ? local.cluster_name : "${var.environment_tag}:${local.cluster_name}" + create_key_pair = var.create_key_pair ? 1 : 0 +} + +# RSA key of size 4096 bits +resource "tls_private_key" "cc-key" { + count = local.create_key_pair + algorithm = "RSA" + rsa_bits = 4096 +} + +resource "local_file" "cc-key-file" { + count = local.create_key_pair + content = tls_private_key.cc-key[0].private_key_pem + filename = var.private-key-file + file_permission = "400" } data "aws_subnet" "rubrik_cloud_cluster" { diff --git a/output.tf b/output.tf index 7540ea1..aed008e 100644 --- a/output.tf +++ b/output.tf @@ -8,4 +8,8 @@ output "rubrik_hosts_sg_id" { output "s3_bucket" { value = module.s3_bucket.s3_bucket_id +} + +output "private_key_file" { + value = var.create_key_pair ? var.private-key-file : null } \ No newline at end of file diff --git a/variables.tf b/variables.tf index 699a413..8c65608 100644 --- a/variables.tf +++ b/variables.tf @@ -34,14 +34,16 @@ variable "aws_iam_instance_profile" { default = "" } -variable "aws_tags" { - description = "Extra tags to add to Rubrik cluster nodes" - type = map(string) - default = {} +variable "create_key_pair" { + description = "If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings." + type = bool + default = true } -variable "aws_subnet_id" { - description = "The VPC Subnet ID to launch Rubrik Cloud Cluster in." +variable "aws_key_pair_name" { + description = "Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used." + type = string + default = "" } variable "aws_public_key" { From cdf6e14fb79e7308c00f5715d3e98a76da324950 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:04:04 -0700 Subject: [PATCH 12/28] Do not refresh nodes if MP image is updated --- modules/rubrik_aws_instances/main.tf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/rubrik_aws_instances/main.tf b/modules/rubrik_aws_instances/main.tf index 20c8974..7a12ca0 100644 --- a/modules/rubrik_aws_instances/main.tf +++ b/modules/rubrik_aws_instances/main.tf @@ -27,7 +27,9 @@ resource "aws_instance" "rubrik_cluster" { vpc_security_group_ids = var.node_config.sg_ids subnet_id = var.node_config.subnet_id key_name = var.node_config.key_pair_name - + lifecycle { + ignore_changes = [ami] + } tags = merge({ Name = each.value }, var.node_config.tags From a24484ee14aa4b31f4c6c7c6caf4b27d37b358a1 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:08:44 -0700 Subject: [PATCH 13/28] Removed support for extranious tags --- main.tf | 15 +++++---------- modules/rubrik_aws_instances/main.tf | 1 + modules/s3_vpc_endpoint/main.tf | 4 +--- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/main.tf b/main.tf index 1cd31fe..b6c441c 100644 --- a/main.tf +++ b/main.tf @@ -84,14 +84,9 @@ module "s3_vpc_endpoint" { create = var.create_s3_vpc_endpoint vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id - #route_table_ids = [data.aws_vpc.rubrik_cloud_cluster.main_route_table_id] - #endpoint_name = (var.s3_vpc_endpoint_name == "" ? "${local.cluster_name}.vpc-ep" : var.s3_vpc_endpoint_name) - tags = merge( - var.aws_tags - ) + tags = var.aws_tags } - ###################################################################### # Create, then configure, the Security Groups for the Rubrik Cluster # ###################################################################### @@ -104,7 +99,7 @@ module "rubrik_nodes_sg" { vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id create = var.create_aws_rubrik_hosts_sg tags = merge( - { name = "${local.cluster_tag}:sg" }, + { name = "${var.cluster_name}:sg" }, var.aws_tags ) } @@ -115,7 +110,7 @@ module "rubrik_nodes_sg_rules" { rubrik_hosts_sg_id = module.rubrik_hosts_sg.security_group_id create = var.create_aws_rubrik_hosts_sg tags = merge( - { name = "${local.cluster_tag}:sg-rule" }, + { name = "${var.cluster_name}:sg-rule" }, var.aws_tags ) depends_on = [ @@ -132,7 +127,7 @@ module "rubrik_hosts_sg" { vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id create = var.create_aws_rubrik_hosts_sg tags = merge( - { name = "${local.cluster_tag}:sg" }, + { name = "${var.cluster_name}:sg" }, var.aws_tags ) } @@ -144,7 +139,7 @@ module "rubrik_hosts_sg_rules" { rubrik_nodes_sg_id = module.rubrik_nodes_sg.security_group_id create = var.create_aws_rubrik_hosts_sg tags = merge( - { name = "${local.cluster_tag}:sg-rule" }, + { name = "${var.cluster_name}:sg-rule" }, var.aws_tags ) depends_on = [ diff --git a/modules/rubrik_aws_instances/main.tf b/modules/rubrik_aws_instances/main.tf index 7a12ca0..90a857f 100644 --- a/modules/rubrik_aws_instances/main.tf +++ b/modules/rubrik_aws_instances/main.tf @@ -39,6 +39,7 @@ resource "aws_instance" "rubrik_cluster" { iam_instance_profile = var.node_config.iam_instance_profile root_block_device { encrypted = true + tags = {Name = "${each.value}-sda"} } } diff --git a/modules/s3_vpc_endpoint/main.tf b/modules/s3_vpc_endpoint/main.tf index 2de37d4..5ca7eda 100644 --- a/modules/s3_vpc_endpoint/main.tf +++ b/modules/s3_vpc_endpoint/main.tf @@ -17,9 +17,7 @@ module "endpoints" { } } - tags = merge( - var.tags, - ) + tags = var.tags } data "aws_vpc_endpoint" "this" { From d839975324c61d26afc67f81ac240687350d9cb1 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:09:43 -0700 Subject: [PATCH 14/28] Updated required Terraform version --- providers.tf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/providers.tf b/providers.tf index 00d6ffe..bbc52c7 100644 --- a/providers.tf +++ b/providers.tf @@ -1,7 +1,5 @@ terraform { -} -terraform { - required_version = ">= 0.15.4" + required_version = ">= 1.2.0" required_providers { aws = { source = "hashicorp/aws" From 7caa16aff0459eff5c55e39dd2ae1c721ba55ba5 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:11:58 -0700 Subject: [PATCH 15/28] Fixed selecting AWS region --- README.md | 3 +-- docs/quick-start.md | 3 +-- providers.tf | 5 +++++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5602ed9..a9873fb 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,7 @@ Here are some resources to get you started! If you find any challenges from this module "rubrik_aws_cloud_cluster" { source = "rubrikinc/rubrik-cloud-cluster/aws" - aws_vpc_security_group_ids = ["sg-0fc82928bd323ed3qq"] - aws_subnet_id = "subnet-0278a40b29e52203a" + aws_region = "us-west-1" cluster_name = "rubrik-cloud-cluster" admin_email = "build@rubrik.com" dns_search_domain = ["rubrikdemo.com"] diff --git a/docs/quick-start.md b/docs/quick-start.md index 3b1ec42..37faf4c 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -10,8 +10,7 @@ In your [Terraform configuration](https://learn.hashicorp.com/terraform/getting- module "rubrik_aws_cloud_cluster" { source = "rubrikinc/rubrik-cloud-cluster/aws" - aws_vpc_security_group_ids = ["sg-0fc82928bd323ed3qq"] - aws_subnet_id = "subnet-0278a40b29e52203a" + aws_region = "us-west-1" cluster_name = "rubrik-cloud-cluster" admin_email = "build@rubrik.com" dns_search_domain = ["rubrikdemo.com"] diff --git a/providers.tf b/providers.tf index bbc52c7..94d6313 100644 --- a/providers.tf +++ b/providers.tf @@ -5,4 +5,9 @@ terraform { source = "hashicorp/aws" } } +} + +# Configure the AWS Provider +provider "aws" { + region = var.aws_region } \ No newline at end of file From 82c89f05cceb0957893c87c41c61085f1e0e97de Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:13:24 -0700 Subject: [PATCH 16/28] Move variables to seperate file --- modules/iam_role/main.tf | 26 ----------------------- modules/iam_role/variables.tf | 25 ++++++++++++++++++++++ modules/rubrik_aws_instances/main.tf | 22 ------------------- modules/rubrik_aws_instances/variables.tf | 21 ++++++++++++++++++ 4 files changed, 46 insertions(+), 48 deletions(-) create mode 100644 modules/iam_role/variables.tf create mode 100644 modules/rubrik_aws_instances/variables.tf diff --git a/modules/iam_role/main.tf b/modules/iam_role/main.tf index 947893d..0af73be 100644 --- a/modules/iam_role/main.tf +++ b/modules/iam_role/main.tf @@ -1,29 +1,3 @@ -variable "bucket" { - type = string -} - -variable "create" { - type = bool - default = true -} - -variable "role_name" { - type = string -} - -variable "role_policy_name" { - type = string -} - -variable "instance_profile_name" { - type = string -} - -variable "tags" { - type = map(string) - default = { } -} - data "template_file" "aws_iam_role_policy" { template = file("cc_es_policy.json.tpl") vars = { diff --git a/modules/iam_role/variables.tf b/modules/iam_role/variables.tf new file mode 100644 index 0000000..cb80613 --- /dev/null +++ b/modules/iam_role/variables.tf @@ -0,0 +1,25 @@ +variable "bucket" { + type = string +} + +variable "create" { + type = bool + default = true +} + +variable "role_name" { + type = string +} + +variable "role_policy_name" { + type = string +} + +variable "instance_profile_name" { + type = string +} + +variable "tags" { + type = map(string) + default = { } +} \ No newline at end of file diff --git a/modules/rubrik_aws_instances/main.tf b/modules/rubrik_aws_instances/main.tf index 90a857f..06441b7 100644 --- a/modules/rubrik_aws_instances/main.tf +++ b/modules/rubrik_aws_instances/main.tf @@ -1,25 +1,3 @@ -variable "node_names" { - type = set(string) -} - -variable "node_config" { - type = object({ - instance_type = string - ami_id = string - sg_ids = set(string) - subnet_id = string - key_pair_name = string - disable_api_termination = bool - iam_instance_profile = string - availability_zone = string - tags = map(string) - }) -} - -variable "disks" { - type = map(any) -} - resource "aws_instance" "rubrik_cluster" { for_each = var.node_names instance_type = var.node_config.instance_type diff --git a/modules/rubrik_aws_instances/variables.tf b/modules/rubrik_aws_instances/variables.tf new file mode 100644 index 0000000..fe25881 --- /dev/null +++ b/modules/rubrik_aws_instances/variables.tf @@ -0,0 +1,21 @@ +variable "node_names" { + type = set(string) +} + +variable "node_config" { + type = object({ + instance_type = string + ami_id = string + sg_ids = set(string) + subnet_id = string + key_pair_name = string + disable_api_termination = bool + iam_instance_profile = string + availability_zone = string + tags = map(string) + }) +} + +variable "disks" { + type = map(any) +} \ No newline at end of file From 59f02a8077db8257ccb5a02ca5d4e325d22ade17 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:17:04 -0700 Subject: [PATCH 17/28] Add support for admin ports --- README.md | 1 + docs/quick-start.md | 1 + main.tf | 9 +++++---- modules/rubrik_nodes_sg/main.tf | 17 ++++++++++++++++- modules/rubrik_nodes_sg/variables.tf | 4 ++++ variables.tf | 8 ++++---- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a9873fb..26160b3 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ The following are the variables accepted by the module. | aws_region | The region to deploy Rubrik Cloud Cluster nodes. | string | | yes | | create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | | aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | +| cloud_cluster_nodes_admin_cidr | The CIDR range for the systems used to administer the Cloud Cluster via SSH and HTTPS. | string | 0.0.0.0/0 | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | | aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | | number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 4 | no | diff --git a/docs/quick-start.md b/docs/quick-start.md index 37faf4c..b61037d 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -29,6 +29,7 @@ The following are the variables accepted by the module. | aws_region | The region to deploy Rubrik Cloud Cluster nodes. | string | | yes | | create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | | aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | +| cloud_cluster_nodes_admin_cidr | The CIDR range for the systems used to administer the Cloud Cluster via SSH and HTTPS. | string | 0.0.0.0/0 | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | | aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | | number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 4 | no | diff --git a/main.tf b/main.tf index b6c441c..d45f15f 100644 --- a/main.tf +++ b/main.tf @@ -105,10 +105,11 @@ module "rubrik_nodes_sg" { } module "rubrik_nodes_sg_rules" { - source = "./modules/rubrik_nodes_sg" - sg_id = module.rubrik_nodes_sg.security_group_id - rubrik_hosts_sg_id = module.rubrik_hosts_sg.security_group_id - create = var.create_aws_rubrik_hosts_sg + source = "./modules/rubrik_nodes_sg" + sg_id = module.rubrik_nodes_sg.security_group_id + rubrik_hosts_sg_id = module.rubrik_hosts_sg.security_group_id + create = var.create_cloud_cluster_hosts_sg + cloud_cluster_nodes_admin_cidr = var.cloud_cluster_nodes_admin_cidr tags = merge( { name = "${var.cluster_name}:sg-rule" }, var.aws_tags diff --git a/modules/rubrik_nodes_sg/main.tf b/modules/rubrik_nodes_sg/main.tf index 09f688e..e986663 100644 --- a/modules/rubrik_nodes_sg/main.tf +++ b/modules/rubrik_nodes_sg/main.tf @@ -38,7 +38,22 @@ module "this" { protocol = -1 source_security_group_id = var.rubrik_hosts_sg_id } - + ] + ingress_with_cidr_blocks = [ + { + from_port = 443 + to_port = 443 + protocol = "tcp" + description = "Admin port for web service" + cidr_blocks = var.cloud_cluster_nodes_admin_cidr + }, + { + from_port = 22 + to_port = 22 + protocol = "tcp" + description = "Admin port for ssh" + cidr_blocks = var.cloud_cluster_nodes_admin_cidr + } ] tags = merge( diff --git a/modules/rubrik_nodes_sg/variables.tf b/modules/rubrik_nodes_sg/variables.tf index 6ed7ee7..bd955a0 100644 --- a/modules/rubrik_nodes_sg/variables.tf +++ b/modules/rubrik_nodes_sg/variables.tf @@ -14,4 +14,8 @@ variable "tags" { variable "rubrik_hosts_sg_id" { type = string +} + +variable "cloud_cluster_nodes_admin_cidr" { + type = string } \ No newline at end of file diff --git a/variables.tf b/variables.tf index 8c65608..aebdbc2 100644 --- a/variables.tf +++ b/variables.tf @@ -66,10 +66,10 @@ variable "cluster_disk_size" { default = "1024" } -variable "cluster_disk_count" { - description = "The number of disks for each node in the cluster. Set to 1 to use with S3 storage for Cloud Cluster ES" - type = number - default = 4 +variable "cloud_cluster_nodes_admin_cidr" { + description = "The CIDR range for the systems used to administer the Cloud Cluster via SSH and HTTPS." + type = string + default = "0.0.0.0/0" } variable "cluster_name" { From 4c35a24337a563a5cc5556acc0149c097ea4798b Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:36:32 -0700 Subject: [PATCH 18/28] fixup! Removed support for extranious tags --- main.tf | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/main.tf b/main.tf index d45f15f..a13a885 100644 --- a/main.tf +++ b/main.tf @@ -2,8 +2,7 @@ # Dynamic Variable Creation # ############################# locals { - cluster_name = var.environment == "" ? var.cluster_name : "${var.environment}.${var.cluster_name}" - cluster_node_names = formatlist("${local.cluster_name}-%02s", range(1, var.number_of_nodes + 1)) + cluster_node_names = formatlist("${var.cluster_name}-%02s", range(1, var.number_of_nodes + 1)) cluster_node_config = { "instance_type" = var.aws_instance_type, "ami_id" = data.aws_ami_ids.rubrik_cloud_cluster.ids[0], @@ -66,7 +65,7 @@ data "aws_ami_ids" "rubrik_cloud_cluster" { module "aws_key_pair" { source = "terraform-aws-modules/key-pair/aws" - key_name = var.aws_key_pair_name == "" ? "${local.cluster_name}.key-pair" : var.aws_key_pair_name + key_name = var.aws_key_pair_name == "" ? "${var.cluster_name}.key-pair" : var.aws_key_pair_name public_key = var.aws_public_key create_key_pair = var.create_key_pair } @@ -94,7 +93,7 @@ module "rubrik_nodes_sg" { source = "terraform-aws-modules/security-group/aws" use_name_prefix = true - name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${local.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name + name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${var.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name description = "Allow hosts to talk to Rubrik Cloud Cluster and Cluster to talk to itself" vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id create = var.create_aws_rubrik_hosts_sg @@ -123,7 +122,7 @@ module "rubrik_hosts_sg" { source = "terraform-aws-modules/security-group/aws" use_name_prefix = true - name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${local.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name + name = var.aws_vpc_cloud_cluster_hosts_sg_name == "" ? "${var.cluster_name}.sg" : var.aws_vpc_cloud_cluster_hosts_sg_name description = "Allow Rubrik Cloud Cluster to talk to hosts, and hosts with this security group can talk to cluster" vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id create = var.create_aws_rubrik_hosts_sg @@ -156,7 +155,7 @@ module "s3_bucket" { source = "terraform-aws-modules/s3-bucket/aws" create_bucket = var.create_s3_bucket - bucket = (var.s3_bucket_name == "" ? "${local.cluster_name}.bucket-do-not-delete" : var.s3_bucket_name) + bucket = var.s3_bucket_name == "" ? "${var.cluster_name}.bucket-do-not-delete" : var.s3_bucket_name acl = "private" } @@ -168,9 +167,9 @@ module "iam_role" { bucket = module.s3_bucket.s3_bucket_id create = var.create_iam_role - role_name = var.aws_cloud_cluster_iam_role_name == "" ? "${local.cluster_name}.role" : var.aws_cloud_cluster_iam_role_name - role_policy_name = var.aws_cloud_cluster_iam_role_policy_name == "" ? "${local.cluster_name}.role-policy" : var.aws_cloud_cluster_iam_role_policy_name - instance_profile_name = var.aws_cloud_cluster_ec2_instance_profile_name == "" ? "${local.cluster_name}.instance-profile" : var.aws_cloud_cluster_ec2_instance_profile_name + role_name = var.aws_cloud_cluster_iam_role_name == "" ? "${var.cluster_name}.role" : var.aws_cloud_cluster_iam_role_name + role_policy_name = var.aws_cloud_cluster_iam_role_policy_name == "" ? "${var.cluster_name}.role-policy" : var.aws_cloud_cluster_iam_role_policy_name + instance_profile_name = var.aws_cloud_cluster_ec2_instance_profile_name == "" ? "${var.cluster_name}.instance-profile" : var.aws_cloud_cluster_ec2_instance_profile_name } ############################### From 0aa8809d2c905c39b5a0035fdd5911ddbb924328 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:45:01 -0700 Subject: [PATCH 19/28] Added support for selecting the latest image --- README.md | 4 ++++ docs/quick-start.md | 44 +++++++++++++++++++++++++++++++++++++++++++- main.tf | 3 ++- variables.tf | 6 ++++-- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 26160b3..0ce59b3 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ module "rubrik_aws_cloud_cluster" { source = "rubrikinc/rubrik-cloud-cluster/aws" aws_region = "us-west-1" + aws_ami_filter = ["rubrik-mp-cc-7*"] cluster_name = "rubrik-cloud-cluster" admin_email = "build@rubrik.com" dns_search_domain = ["rubrikdemo.com"] @@ -32,8 +33,11 @@ The following are the variables accepted by the module. | Name | Description | Type | Default | Required | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | | aws_region | The region to deploy Rubrik Cloud Cluster nodes. | string | | yes | +| aws_ami_filter | Cloud Cluster AWS AMI name pattern(s) to search for. Use [\"rubrik-mp-cc-*\"]. Where is the major version of CDM. | list | | yes | +| aws_image_id | AWS Image ID to deploy. Set to 'latest' or leave blank to deploy the latest version as determined by `aws_ami_filter`. | string | latest | no | | create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | | aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | +*Note: The `aws_ami_filter` and `aws_ami_owners` variables are only used when the `aws_image_id` variable is blank or set to `latest`* | cloud_cluster_nodes_admin_cidr | The CIDR range for the systems used to administer the Cloud Cluster via SSH and HTTPS. | string | 0.0.0.0/0 | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | | aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | diff --git a/docs/quick-start.md b/docs/quick-start.md index b61037d..caeaee0 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -11,6 +11,7 @@ module "rubrik_aws_cloud_cluster" { source = "rubrikinc/rubrik-cloud-cluster/aws" aws_region = "us-west-1" + aws_ami_filter = ["rubrik-mp-cc-7*"] cluster_name = "rubrik-cloud-cluster" admin_email = "build@rubrik.com" dns_search_domain = ["rubrikdemo.com"] @@ -27,8 +28,10 @@ The following are the variables accepted by the module. | Name | Description | Type | Default | Required | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | | aws_region | The region to deploy Rubrik Cloud Cluster nodes. | string | | yes | +| aws_ami_filter | Cloud Cluster AWS AMI name pattern(s) to search for. Use [\"rubrik-mp-cc-*\"]. Where is the major version of CDM. | list | | yes | | create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | | aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | +*Note: The `aws_ami_filter` and `aws_ami_owners` variables are only used when the `aws_image_id` variable is blank or set to `latest`* | cloud_cluster_nodes_admin_cidr | The CIDR range for the systems used to administer the Cloud Cluster via SSH and HTTPS. | string | 0.0.0.0/0 | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | | aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | @@ -91,7 +94,7 @@ commands will detect it and remind you to do so if necessary. ### Gain Access to the Rubrik Cloud Cluster AMI -The Terraform script will automatically install the latest version of Rubrik Cloud Cluster from the AWS Marketplace. If a different version of Cloud Cluster is required modify the filters in the `data "aws_ami_ids" "rubrik_cloud_cluster"` section of the Terraform script. +The Terraform script will automatically install the latest maintenance release of Rubrik Cloud Cluster major version (as defined by the `aws_ami_filter` variable) from the AWS Marketplace. If a different version of Cloud Cluster is required modify the filters in the `aws_image_id`, `aws_ami_owners` and/or `aws_ami_filter` variables. ### Planning @@ -109,3 +112,42 @@ The Cloud Cluster can now be configured through the Web UI; access to the interf ### Destroying Once the Cloud Cluster is no longer required, it can be destroyed using the `terraform destroy` command, and entering `yes` when prompted. This will also destroy the attached EBS volumes. + +## Selecting a specific image + +To select a specific image to deploy replace the `aws_image_id` variable with the AMI ID of the Rubrik Marketplace Image to deploy. To find a list of the Rubrik Cloud Cluster images that are available in a specific region run the following `aws` cli command (requires that the AWS CLI be installed): + +```none + aws ec2 describe-images \ + --filters 'Name=owner-id,Values=679593333241' 'Name=name,Values=rubrik-mp-cc-*' \ + --query 'sort_by(Images, &CreationDate)[*].{"Create Date":CreationDate, "Image ID":ImageId, Version:Description}' \ + --region '' \ + --output table +``` + +Where is the major version of Rubrik CDM (ex. `rubrik-mp-cc-7*`) + +Example: + +```none +aws ec2 describe-images \ + --filters 'Name=owner-id,Values=679593333241' 'Name=name,Values=rubrik-mp-cc-7*' \ + --query 'sort_by(Images, &CreationDate)[*].{"Create Date":CreationDate, "Image ID":ImageId, Version:Description}' \ + --region 'us-west-2' \ + --output table + +------------------------------------------------------------------------------------------ +| DescribeImages | ++--------------------------+-------------------------+-----------------------------------+ +| Create Date | Image ID | Version | ++--------------------------+-------------------------+-----------------------------------+ +| 2022-02-04T21:49:48.000Z| ami-0056ddcc69df6fb5c | Rubrik OS rubrik-7-0-0-14764 | +| 2022-04-01T00:13:58.000Z| ami-026233b876a279622 | Rubrik OS rubrik-7-0-1-15183 | +| 2022-04-12T04:50:31.000Z| ami-03d68b150241012ec | Rubrik OS rubrik-7-0-1-p1-15197 | +| 2022-04-27T05:56:27.000Z| ami-09a3baba1545aa5f7 | Rubrik OS rubrik-7-0-1-p2-15336 | +| 2022-05-13T21:51:54.000Z| ami-0af1ff3ee7517fefa | Rubrik OS rubrik-7-0-1-p3-15425 | +| 2022-05-20T00:01:55.000Z| ami-0cc1db55e45f3109b | Rubrik OS rubrik-7-0-1-p4-15453 | +| 2022-05-26T19:08:31.000Z| ami-04d6af7c6f6629ce1 | Rubrik OS rubrik-7-0-2-15510 | ++--------------------------+-------------------------+-----------------------------------+ +``` + diff --git a/main.tf b/main.tf index a13a885..55ff321 100644 --- a/main.tf +++ b/main.tf @@ -3,9 +3,10 @@ ############################# locals { cluster_node_names = formatlist("${var.cluster_name}-%02s", range(1, var.number_of_nodes + 1)) + ami_id = var.aws_image_id == "" || var.aws_image_id == "latest" ? data.aws_ami_ids.rubrik_cloud_cluster.ids[0] : var.aws_image_id cluster_node_config = { "instance_type" = var.aws_instance_type, - "ami_id" = data.aws_ami_ids.rubrik_cloud_cluster.ids[0], + "ami_id" = local.ami_id, "sg_ids" = concat(var.aws_cloud_cluster_nodes_sg_ids, [module.rubrik_nodes_sg.security_group_id]), "subnet_id" = var.aws_subnet_id, "key_pair_name" = local.aws_key_pair_name, diff --git a/variables.tf b/variables.tf index aebdbc2..be65f13 100644 --- a/variables.tf +++ b/variables.tf @@ -28,8 +28,10 @@ variable "aws_cloud_cluster_nodes_sg_ids" { default = [] } -variable "aws_iam_instance_profile" { - description = "IAM instance profile for accessing S3 with Cloud Cluster ES" +variable "aws_ami_filter" { + description = "Cloud Cluster AWS AMI name pattern(s) to search for. Use [\"rubrik-mp-cc-*\"]. Where is the major version of CDM. Ex. [\"rubrik-mp-cc-7\"]" + type = set(string) +} type = string default = "" } From 6fc5427e86ba529b527e8c0c558e56fad6e08abd Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:47:15 -0700 Subject: [PATCH 20/28] Fixed empty aws_cloud_cluster_nodes_sg_ids issue --- main.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 55ff321..4f7ed98 100644 --- a/main.tf +++ b/main.tf @@ -4,10 +4,11 @@ locals { cluster_node_names = formatlist("${var.cluster_name}-%02s", range(1, var.number_of_nodes + 1)) ami_id = var.aws_image_id == "" || var.aws_image_id == "latest" ? data.aws_ami_ids.rubrik_cloud_cluster.ids[0] : var.aws_image_id + sg_ids = var.aws_cloud_cluster_nodes_sg_ids == "" ? [module.rubrik_nodes_sg.security_group_id] : concat(var.aws_cloud_cluster_nodes_sg_ids, [module.rubrik_nodes_sg.security_group_id]) cluster_node_config = { "instance_type" = var.aws_instance_type, "ami_id" = local.ami_id, - "sg_ids" = concat(var.aws_cloud_cluster_nodes_sg_ids, [module.rubrik_nodes_sg.security_group_id]), + "sg_ids" = local.sg_ids, "subnet_id" = var.aws_subnet_id, "key_pair_name" = local.aws_key_pair_name, "disable_api_termination" = var.aws_disable_api_termination, From 61aa3341551ea996fff2b34b65e2e8ea2b6aff36 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:49:16 -0700 Subject: [PATCH 21/28] fixup! Added support for creating SSH key pair --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 4f7ed98..e62788e 100644 --- a/main.tf +++ b/main.tf @@ -68,7 +68,7 @@ module "aws_key_pair" { source = "terraform-aws-modules/key-pair/aws" key_name = var.aws_key_pair_name == "" ? "${var.cluster_name}.key-pair" : var.aws_key_pair_name - public_key = var.aws_public_key + public_key = var.aws_public_key == "" ? tls_private_key.cc-key[0].public_key_openssh : var.aws_public_key create_key_pair = var.create_key_pair } From 011e80c8f2ff5cf8d1604f6192fb057886b99f42 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:52:38 -0700 Subject: [PATCH 22/28] Updated variable name for clarity --- README.md | 1 + docs/quick-start.md | 1 + main.tf | 6 +++--- variables.tf | 8 ++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0ce59b3..88dd57b 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ The following are the variables accepted by the module. | aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | *Note: The `aws_ami_filter` and `aws_ami_owners` variables are only used when the `aws_image_id` variable is blank or set to `latest`* | cloud_cluster_nodes_admin_cidr | The CIDR range for the systems used to administer the Cloud Cluster via SSH and HTTPS. | string | 0.0.0.0/0 | no | +| create_cloud_cluster_hosts_sg | If true, creates a new Security Group for node to host traffic from the Rubrik cluster. | string | true | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | | aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | | number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 4 | no | diff --git a/docs/quick-start.md b/docs/quick-start.md index caeaee0..f7632d0 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -33,6 +33,7 @@ The following are the variables accepted by the module. | aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | *Note: The `aws_ami_filter` and `aws_ami_owners` variables are only used when the `aws_image_id` variable is blank or set to `latest`* | cloud_cluster_nodes_admin_cidr | The CIDR range for the systems used to administer the Cloud Cluster via SSH and HTTPS. | string | 0.0.0.0/0 | no | +| create_cloud_cluster_hosts_sg | If true, creates a new Security Group for node to host traffic from the Rubrik cluster. | string | true | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | | aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | | number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 4 | no | diff --git a/main.tf b/main.tf index e62788e..c06b576 100644 --- a/main.tf +++ b/main.tf @@ -98,7 +98,7 @@ module "rubrik_nodes_sg" { name = var.aws_vpc_cloud_cluster_nodes_sg_name == "" ? "${var.cluster_name}.sg" : var.aws_vpc_cloud_cluster_nodes_sg_name description = "Allow hosts to talk to Rubrik Cloud Cluster and Cluster to talk to itself" vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id - create = var.create_aws_rubrik_hosts_sg + create = var.create_cloud_cluster_hosts_sg tags = merge( { name = "${var.cluster_name}:sg" }, var.aws_tags @@ -127,7 +127,7 @@ module "rubrik_hosts_sg" { name = var.aws_vpc_cloud_cluster_hosts_sg_name == "" ? "${var.cluster_name}.sg" : var.aws_vpc_cloud_cluster_hosts_sg_name description = "Allow Rubrik Cloud Cluster to talk to hosts, and hosts with this security group can talk to cluster" vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id - create = var.create_aws_rubrik_hosts_sg + create = var.create_cloud_cluster_hosts_sg tags = merge( { name = "${var.cluster_name}:sg" }, var.aws_tags @@ -139,7 +139,7 @@ module "rubrik_hosts_sg_rules" { sg_id = module.rubrik_hosts_sg.security_group_id rubrik_nodes_sg_id = module.rubrik_nodes_sg.security_group_id - create = var.create_aws_rubrik_hosts_sg + create = var.create_cloud_cluster_hosts_sg tags = merge( { name = "${var.cluster_name}:sg-rule" }, var.aws_tags diff --git a/variables.tf b/variables.tf index be65f13..5bedd3a 100644 --- a/variables.tf +++ b/variables.tf @@ -73,10 +73,10 @@ variable "cloud_cluster_nodes_admin_cidr" { type = string default = "0.0.0.0/0" } - -variable "cluster_name" { - description = "Unique name to assign to the Rubrik Cloud Cluster. This will also be used to populate the EC2 instance name tag. For example, rubrik-cloud-cluster-1, rubrik-cloud-cluster-2 etc." - default = "rubrik-cloud-cluster" +variable "create_cloud_cluster_hosts_sg" { + description = "If true, creates a new Security Group for node to host traffic from the Rubrik cluster." + type = bool + default = true } variable "admin_email" { From 2f3f70c7b71fda2367c47354edc0cd387594125a Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:54:24 -0700 Subject: [PATCH 23/28] Restuctured to make docs consistent --- README.md | 62 +++++++++++++-- docs/quick-start.md | 63 +++++++++++++-- variables.tf | 190 ++++++++++++++++++++++---------------------- 3 files changed, 206 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 88dd57b..7e2c097 100644 --- a/README.md +++ b/README.md @@ -30,27 +30,77 @@ module "rubrik_aws_cloud_cluster" { The following are the variables accepted by the module. +#### Instance/Node Settings + | Name | Description | Type | Default | Required | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | | aws_region | The region to deploy Rubrik Cloud Cluster nodes. | string | | yes | +| aws_instance_type | The type of instance to use as Rubrik Cloud Cluster nodes. CC-ES requires m5.4xlarge. | string | m5.4xlarge | no | +| aws_disable_api_termination | If true, enables EC2 Instance Termination Protection on the Rubrik Cloud Cluster nodes. | bool | true | no | +| aws_tags | Tags to add to the resources that this Terraform script creates, including the Rubrik cluster nodes. | map | | no | +| number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 3 | no | +| aws_ami_owners | AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs. | list | ["679593333241"] | no | | aws_ami_filter | Cloud Cluster AWS AMI name pattern(s) to search for. Use [\"rubrik-mp-cc-*\"]. Where is the major version of CDM. | list | | yes | | aws_image_id | AWS Image ID to deploy. Set to 'latest' or leave blank to deploy the latest version as determined by `aws_ami_filter`. | string | latest | no | | create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | | aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | +| aws_public_key | The public key material needed to create an AWS Key-Pair for use with Rubrik Cloud Cluster. | string | | no | +| private-key-file | If a new AWS SSH Key-Pair is generated, the name of the file to save the private key material in. | string | ./.terraform/cc-key.pem | no | + +*Note: When using the `aws_tags` variable, the "Name" tag is automatically used by this TF for those resources that support it.* + *Note: The `aws_ami_filter` and `aws_ami_owners` variables are only used when the `aws_image_id` variable is blank or set to `latest`* + +*Note: When using the `aws_image_id` variable, see [Selecting a specific image](#selecting-a-specific-image) for details on finding images.* + +*Note: When using the `aws_key_pair_name` variable, if a new AWS SSH Key-Pair is being created and no name is specified, a name will be automatically generated.* + +*Note: When using the `aws_public_key` variable, if a new AWS SSH Key-Pair is being created and no material is provided, new key material will be auto generated.* + +
+ +#### Network Settings + +| Name | Description | Type | Default | Required | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | +| create_cloud_cluster_nodes_sg | If true, creates a new Security Group for node to node traffic within the Rubrik cluster. | bool | true | no | +| aws_vpc_cloud_cluster_nodes_sg_name | The name of the security group to create for Rubrik Cloud Cluster to use. | string | Rubrik Cloud Cluster | no | | cloud_cluster_nodes_admin_cidr | The CIDR range for the systems used to administer the Cloud Cluster via SSH and HTTPS. | string | 0.0.0.0/0 | no | | create_cloud_cluster_hosts_sg | If true, creates a new Security Group for node to host traffic from the Rubrik cluster. | string | true | no | +| aws_vpc_cloud_cluster_hosts_sg_name | The name of the security group to create for Rubrik Cloud Cluster to communicate with EC2 instances. | string | Rubrik Cloud Cluster Hosts | no | +| aws_cloud_cluster_nodes_sg_ids | Additional security groups to add to Rubrik cluster nodes. | string | | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | -| aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | -| number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 4 | no | -| cluster_disk_type | The disk type to use for Rubrik Cloud Cluster data disks (sc1 or st1). NOTE: st1 disks require six 8TB disks. | string | st1 | yes | -| cluster_disk_count | The number of disks to use per node. Set to zero to leverage S3 object storage if deploying Cloud Cluster ES | number | 4 | no | + +#### Storage Settings + +| Name | Description | Type | Default | Required | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | +| cluster_disk_type | Disk type for the data disks (st1, sc1 or gp2). Use gp2 for CC-ES. Use sc1 for 48TB CC nodes. Use st1 for all others. | string | gp2 | no | +| cluster_disk_size | The size (in GB) of each data disk on each node. Cloud Cluster ES only requires 1 512 GB disk per node. | string | 512 | no | +| cluster_disk_count | The number of disks for each node in the cluster. Set to 1 to use with S3 storage for Cloud Cluster ES. | int | 1 | no | + +#### Cloud Cluster ES Settings + +| Name | Description | Type | Default | Required | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | +| create_iam_role | If true, create required IAM role, role policy, and instance profile needed for Cloud Cluster ES. | bool | true | no | +| aws_cloud_cluster_iam_role_name | AWS IAM Role name for Cloud Cluster ES. If blank a name will be auto generated. Required if create_iam_role is false. | string | | no | +| aws_cloud_cluster_iam_role_policy_name | AWS IAM Role policy name for Cloud Cluster ES if create_iam_role is true. If blank a name will be auto generated. | string | | no | +| aws_cloud_cluster_ec2_instance_profile_name | AWS EC2 Instance Profile name that links the IAM Role to Cloud Cluster ES. If blank a name will be auto generated. | string | | no | +| create_s3_bucket | If true, create am S3 bucket for Cloud Cluster ES data storage. | bool | true | no | +| s3_bucket_name | Name of the S3 bucket to use with Cloud Cluster ES data storage. If blank a name will be auto generated. | string | | no | +| create_s3_vpc_endpoint | If true, create a VPC Endpoint and S3 Endpoint Service for Cloud Cluster ES. | bool | true | no | + +#### Bootstrap Settings + +| Name | Description | Type | Default | Required | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | | cluster_name | Unique name to assign to Rubrik Cloud Cluster. Also used for EC2 instance name tag. For example, rubrik-1, rubrik-2 etc. | string | | yes | | admin_email | The Rubrik Cloud Cluster sends messages for the admin account to this email address. | string | | yes | | admin_password | Password for the Rubrik Cloud Cluster admin account. | string | RubrikGoForward | no | | dns_search_domain | List of search domains that the DNS Service will use to resolve hostnames that are not fully qualified. | list | | yes | -| dns_name_servers | List of the IPv4 addresses of the DNS servers. | list | | yes | -| ntp_servers | List of FQDN or IPv4 addresses of a network time protocol (NTP) server(s) | list | ["8.8.8.8"] | no | +| dns_name_servers | List of the IPv4 addresses of the DNS servers. | list | ["169.254.169.253"] | no | +| ntp_servers | List of FQDN or IPv4 addresses of a network time protocol (NTP) server(s) | list | ["169.254.169.123"] | no | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | int | 15 | no | ## Prerequisites diff --git a/docs/quick-start.md b/docs/quick-start.md index f7632d0..e5bf478 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -25,26 +25,77 @@ You may also add additional variables, such as `ntp_servers`, to overwrite the d The following are the variables accepted by the module. +### Instance/Node Settings + | Name | Description | Type | Default | Required | | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | | aws_region | The region to deploy Rubrik Cloud Cluster nodes. | string | | yes | +| aws_instance_type | The type of instance to use as Rubrik Cloud Cluster nodes. CC-ES requires m5.4xlarge. | string | m5.4xlarge | no | +| aws_disable_api_termination | If true, enables EC2 Instance Termination Protection on the Rubrik Cloud Cluster nodes. | bool | true | no | +| aws_tags | Tags to add to the resources that this Terraform script creates, including the Rubrik cluster nodes. | map | | no | +| number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 3 | no | +| aws_ami_owners | AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs. | list | ["679593333241"] | no | | aws_ami_filter | Cloud Cluster AWS AMI name pattern(s) to search for. Use [\"rubrik-mp-cc-*\"]. Where is the major version of CDM. | list | | yes | +| aws_image_id | AWS Image ID to deploy. Set to 'latest' or leave blank to deploy the latest version as determined by `aws_ami_filter`. | string | latest | no | | create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | | aws_key_pair_name | Name for the AWS SSH Key-Pair being created or the existing AWS SSH Key-Pair being used. | string | | no | +| aws_public_key | The public key material needed to create an AWS Key-Pair for use with Rubrik Cloud Cluster. | string | | no | +| private-key-file | If a new AWS SSH Key-Pair is generated, the name of the file to save the private key material in. | string | ./.terraform/cc-key.pem | no | + +*Note: When using the `aws_tags` variable, the "Name" tag is automatically used by this TF for those resources that support it.* + *Note: The `aws_ami_filter` and `aws_ami_owners` variables are only used when the `aws_image_id` variable is blank or set to `latest`* + +*Note: When using the `aws_image_id` variable, see [Selecting a specific image](#selecting-a-specific-image) for details on finding images.* + +*Note: When using the `aws_key_pair_name` variable, if a new AWS SSH Key-Pair is being created and no name is specified, a name will be automatically generated.* + +*Note: When using the `aws_public_key` variable, if a new AWS SSH Key-Pair is being created and no material is provided, new key material will be auto generated.* + +
+ +### Network Settings + +| Name | Description | Type | Default | Required | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | +| create_cloud_cluster_nodes_sg | If true, creates a new Security Group for node to node traffic within the Rubrik cluster. | bool | true | no | +| aws_vpc_cloud_cluster_nodes_sg_name | The name of the security group to create for Rubrik Cloud Cluster to use. | string | Rubrik Cloud Cluster | no | | cloud_cluster_nodes_admin_cidr | The CIDR range for the systems used to administer the Cloud Cluster via SSH and HTTPS. | string | 0.0.0.0/0 | no | | create_cloud_cluster_hosts_sg | If true, creates a new Security Group for node to host traffic from the Rubrik cluster. | string | true | no | +| aws_vpc_cloud_cluster_hosts_sg_name | The name of the security group to create for Rubrik Cloud Cluster to communicate with EC2 instances. | string | Rubrik Cloud Cluster Hosts | no | +| aws_cloud_cluster_nodes_sg_ids | Additional security groups to add to Rubrik cluster nodes. | string | | no | | aws_subnet_id | The VPC Subnet ID to launch Rubrik Cloud Cluster in. | string | | yes | -| aws_public_key | he public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster. | string | | yes | -| number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 4 | no | -| cluster_disk_type | The disk type to use for Rubrik Cloud Cluster data disks (sc1 or st1). NOTE: st1 disks require six 8TB disks. | string | st1 | yes | -| cluster_disk_size | The size of each the three data disks in each node. | string | 1024 | no | + +### Storage Settings + +| Name | Description | Type | Default | Required | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | +| cluster_disk_type | Disk type for the data disks (st1, sc1 or gp2). Use gp2 for CC-ES. Use sc1 for 48TB CC nodes. Use st1 for all others. | string | gp2 | no | +| cluster_disk_size | The size (in GB) of each data disk on each node. Cloud Cluster ES only requires 1 512 GB disk per node. | string | 512 | no | +| cluster_disk_count | The number of disks for each node in the cluster. Set to 1 to use with S3 storage for Cloud Cluster ES. | int | 1 | no | + +### Cloud Cluster ES Settings + +| Name | Description | Type | Default | Required | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | +| create_iam_role | If true, create required IAM role, role policy, and instance profile needed for Cloud Cluster ES. | bool | true | no | +| aws_cloud_cluster_iam_role_name | AWS IAM Role name for Cloud Cluster ES. If blank a name will be auto generated. Required if create_iam_role is false. | string | | no | +| aws_cloud_cluster_iam_role_policy_name | AWS IAM Role policy name for Cloud Cluster ES if create_iam_role is true. If blank a name will be auto generated. | string | | no | +| aws_cloud_cluster_ec2_instance_profile_name | AWS EC2 Instance Profile name that links the IAM Role to Cloud Cluster ES. If blank a name will be auto generated. | string | | no | +| create_s3_bucket | If true, create am S3 bucket for Cloud Cluster ES data storage. | bool | true | no | +| s3_bucket_name | Name of the S3 bucket to use with Cloud Cluster ES data storage. If blank a name will be auto generated. | string | | no | +| create_s3_vpc_endpoint | If true, create a VPC Endpoint and S3 Endpoint Service for Cloud Cluster ES. | bool | true | no | + +### Bootstrap Settings + +| Name | Description | Type | Default | Required | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | :----: | :------------------------: | :------: | | cluster_name | Unique name to assign to Rubrik Cloud Cluster. Also used for EC2 instance name tag. For example, rubrik-1, rubrik-2 etc. | string | | yes | | admin_email | The Rubrik Cloud Cluster sends messages for the admin account to this email address. | string | | yes | | admin_password | Password for the Rubrik Cloud Cluster admin account. | string | RubrikGoForward | no | | dns_search_domain | List of search domains that the DNS Service will use to resolve hostnames that are not fully qualified. | list | | yes | -| dns_name_servers | List of the IPv4 addresses of the DNS servers. | list | | yes | -| ntp_servers | List of FQDN or IPv4 addresses of a network time protocol (NTP) server(s) | list | ["8.8.8.8"] | no | +| dns_name_servers | List of the IPv4 addresses of the DNS servers. | list | ["169.254.169.253"] | no | +| ntp_servers | List of FQDN or IPv4 addresses of a network time protocol (NTP) server(s) | list | ["169.254.169.123"] | no | | timeout | The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error. | int | 15 | no | ## Running the Terraform Configuration diff --git a/variables.tf b/variables.tf index 5bedd3a..acd1e49 100644 --- a/variables.tf +++ b/variables.tf @@ -1,9 +1,10 @@ +# Instance/Node Settings variable "aws_region" { description = "The region to deploy Rubrik Cloud Cluster nodes." } variable "aws_instance_type" { - description = "The type of instance to use as Rubrik Cloud Cluster nodes." + description = "The type of instance to use as Rubrik Cloud Cluster nodes. CC-ES requires m5.4xlarge." default = "m5.4xlarge" } @@ -12,28 +13,32 @@ variable "aws_disable_api_termination" { default = true } -variable "aws_vpc_cloud_cluster_nodes_sg_name" { - description = "The name of the security group to create for Rubrik Cloud Cluster to use." - default = "Rubrik Cloud Cluster" +variable "aws_tags" { + description = "Tags to add to the AWS resources that this Terraform script creates, including the Rubrik cluster nodes." + type = map(string) + default = {} } -variable "aws_vpc_cloud_cluster_hosts_sg_name" { - description = "The name of the security group to create for Rubrik Cloud Cluster to communicate with EC2 instances." - default = "Rubrik Cloud Cluster Hosts" +variable "number_of_nodes" { + description = "The total number of nodes in Rubrik Cloud Cluster." + default = 3 } -variable "aws_cloud_cluster_nodes_sg_ids" { - description = "Extra security groups to add to Rubrik cluster nodes" - type = list(string) - default = [] +variable "aws_ami_owners" { + description = "AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs." + type = set(string) + default = ["679593333241"] } variable "aws_ami_filter" { description = "Cloud Cluster AWS AMI name pattern(s) to search for. Use [\"rubrik-mp-cc-*\"]. Where is the major version of CDM. Ex. [\"rubrik-mp-cc-7\"]" type = set(string) } + +variable "aws_image_id" { + description = "AWS Image ID to deploy. Set to 'latest' or leave blank to deploy the latest version from the marketplace." type = string - default = "" + default = "latest" } variable "create_key_pair" { @@ -49,23 +54,25 @@ variable "aws_key_pair_name" { } variable "aws_public_key" { - description = "The public key material needed to create an AWS key pair for use with Rubrik Cloud Cluster." + description = "The public key material needed to create an AWS Key-Pair for use with Rubrik Cloud Cluster. " sensitive = true + default = "" } - -variable "number_of_nodes" { - description = "The total number of nodes in Rubrik Cloud Cluster." - default = 4 +variable "private-key-file" { + description = "If a new AWS SSH Key-Pair is generated, the name of the file to save the private key material in." + type = string + default = "./.terraform/cc-key.pem" } -variable "cluster_disk_type" { - description = "The disk type to use for Rubrik Cloud Cluster data disks (sc1 or st1). NOTE: st1 disks require six 8TB disks." - default = "st1" +# Network Settings +variable "create_cloud_cluster_nodes_sg" { + description = "If true, creates a new Security Group for node to node traffic within the Rubrik cluster." + type = bool + default = true } - -variable "cluster_disk_size" { - description = "The size of each the three data disks in each node." - default = "1024" +variable "aws_vpc_cloud_cluster_nodes_sg_name" { + description = "The name of the security group to create for Rubrik Cloud Cluster to use." + default = "Rubrik Cloud Cluster Nodes" } variable "cloud_cluster_nodes_admin_cidr" { @@ -78,125 +85,114 @@ variable "create_cloud_cluster_hosts_sg" { type = bool default = true } - -variable "admin_email" { - description = "The Rubrik Cloud Cluster sends messages for the admin account to this email address." -} - -variable "admin_password" { - description = "Password for the Rubrik Cloud Cluster admin account." - default = "RubrikGoForward" +variable "aws_vpc_cloud_cluster_hosts_sg_name" { + description = "The name of the security group to create for Rubrik Cloud Cluster to communicate with EC2 instances." + default = "Rubrik Cloud Cluster Hosts" } -variable "dns_search_domain" { - type = list(any) - description = "List of search domains that the DNS Service will use to resolve hostnames that are not fully qualified." +variable "aws_cloud_cluster_nodes_sg_ids" { + description = "Additional security groups to add to Rubrik cluster nodes." + type = list(string) default = [] } -variable "dns_name_servers" { - type = list(any) - description = "List of the IPv4 addresses of the DNS servers." - default = ["169.254.169.253"] +variable "aws_subnet_id" { + description = "The VPC Subnet ID to launch Rubrik Cloud Cluster in." } -variable "ntp_servers" { - description = "List of FQDN or IPv4 addresses of a network time protocol (NTP) server(s)" - default = ["169.254.169.123"] +# Storage Settings +variable "cluster_disk_type" { + description = "Disk type for the data disks (st1, sc1 or gp2). Use gp2 for CC-ES. Use sc1 for 48TB CC nodes. Use st1 for all others. " + default = "gp2" } -variable "timeout" { - description = "The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error." - default = 15 +variable "cluster_disk_size" { + description = "The size (in GB) of each data disk on each node. Cloud Cluster ES only requires 1 512 GB disk per node." + default = "512" } -variable "aws_ami_owners" { - description = "Set of AWS Account that own the Rubrik Cloud Cluster AMI" - type = set(string) - default = ["679593333241"] +variable "cluster_disk_count" { + description = "The number of disks for each node in the cluster. Set to 1 to use with S3 storage for Cloud Cluster ES." + type = number + default = 1 } -variable "aws_ami_filter" { - description = "Set of AWS AMI names to search for" - type = set(string) - default = ["rubrik-mp-cc-*"] +# Cloud Cluster ES Settings +variable "create_iam_role" { + description = "If true, create required IAM role, role policy, and instance profile needed for Cloud Cluster ES." + type = bool + default = true } -variable "environment_tag" { - description = "Prefix used to identify an environment for tagging like \"prod\" or \"europe:shared:dev\"" +variable "aws_cloud_cluster_iam_role_name" { + description = "AWS IAM Role name for Cloud Cluster ES. If blank a name will be auto generated. Required if create_iam_role is false." type = string default = "" } -variable "environment" { - description = "Prefix used to identify an environment for to be added to names like \"prod\" or \"europe-shared-dev\"" +variable "aws_cloud_cluster_iam_role_policy_name" { + description = "AWS IAM Role policy name for Cloud Cluster ES if create_iam_role is true. If blank a name will be auto generated." type = string default = "" } -variable "aws_key_pair_name" { - description = "Name used to identify a new or existing AWS SSH Key-Pair" +variable "aws_cloud_cluster_ec2_instance_profile_name" { + description = "AWS EC2 Instance Profile name that links the IAM Role to Cloud Cluster ES. If blank a name will be auto generated." type = string default = "" } -variable "create_key_pair" { - description = "Should a new AWS SSH Key-Pair be created?" - type = bool - default = true -} - -variable "create_aws_rubrik_nodes_sg" { - description = "Should a new Security Group be created for node to node traffic within the Rubrik cluster?" +variable "create_s3_bucket" { + description = "If true, create am S3 bucket for Cloud Cluster ES data storage." type = bool default = true } -variable "create_aws_rubrik_hosts_sg" { - description = "Should a new Security Group be created for node to host traffic from the Rubrik cluster?" - type = bool - default = true +variable "s3_bucket_name" { + description = "Name of the S3 bucket to use with Cloud Cluster ES data storage. If blank a name will be auto generated." + type = string + default = "" } -variable "create_iam_role" { - description = "Should the required IAM role, role policy, and instance profile be created?" +variable "create_s3_vpc_endpoint" { + description = "If true, create a VPC Endpoint and S3 Endpoint Service for Cloud Cluster ES. " type = bool default = true } -variable "create_s3_vpc_endpoint" { - description = "Should the required VPC Endpoint and S3 Endpoint Service for Cloud Cluster ES be created?" - type = bool - default = false +# Bootstrap Settings +variable "cluster_name" { + description = "Unique name to assign to the Rubrik Cloud Cluster. This will also be used to populate the EC2 instance name tag. For example, rubrik-cloud-cluster-1, rubrik-cloud-cluster-2 etc." + default = "rubrik-cloud-cluster" } -variable "create_s3_bucket" { - description = "Should the required S3 bucket for Cloud Cluster ES be created?" - type = bool - default = false +variable "admin_email" { + description = "The Rubrik Cloud Cluster sends messages for the admin account to this email address." } -variable "s3_bucket_name" { - description = "Optional name to assign the S3 bucket" - type = string - default = "" +variable "admin_password" { + description = "Password for the Rubrik Cloud Cluster admin account." + default = "RubrikGoForward" } -variable "aws_cloud_cluster_iam_role_name" { - description = "Optional name to assign to the AWS IAM Role that is used to access S3" - type = string - default = "" +variable "dns_search_domain" { + type = list(any) + description = "List of search domains that the DNS Service will use to resolve hostnames that are not fully qualified." + default = [] } -variable "aws_cloud_cluster_iam_role_policy_name" { - description = "Optional name to assign to the AWS IAM Role policy that is used to access S3" - type = string - default = "" +variable "dns_name_servers" { + type = list(any) + description = "List of the IPv4 addresses of the DNS servers." + default = ["169.254.169.253"] } -variable "aws_cloud_cluster_ec2_instance_profile_name" { - description = "Optional name to assign to the AWS EC2 Instance Profile that links the IAM Role to the cluster" - type = string - default = "" +variable "ntp_servers" { + description = "List of FQDN or IPv4 addresses of a network time protocol (NTP) server(s)" + default = ["169.254.169.123"] } +variable "timeout" { + description = "The number of seconds to wait to establish a connection the Rubrik cluster before returning a timeout error." + default = 15 +} \ No newline at end of file From 71d840062993e9894b6a6a5fc0afbf4594f53143 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 14:55:35 -0700 Subject: [PATCH 24/28] Genreal Documentation Update --- README.md | 10 +++++- docs/quick-start.md | 83 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 7e2c097..71e99db 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ module "rubrik_aws_cloud_cluster" { source = "rubrikinc/rubrik-cloud-cluster/aws" aws_region = "us-west-1" + aws_subnet_id = "subnet-1234567890abcdefg" aws_ami_filter = ["rubrik-mp-cc-7*"] cluster_name = "rubrik-cloud-cluster" admin_email = "build@rubrik.com" @@ -107,10 +108,17 @@ The following are the variables accepted by the module. There are a few services you'll need in order to get this project off the ground: -- [Terraform](https://www.terraform.io/downloads.html) v0.15.4 or greater +- [Terraform](https://www.terraform.io/downloads.html) v1.2.2 or greater - [Rubrik Provider for Terraform](https://github.com/rubrikinc/rubrik-provider-for-terraform) - provides Terraform functions for Rubrik - Only required to run the sample Rubrik Bootstrap command +- The Rubik Cloud Cluster product in the AWS Marketplace must be subscribed to. Otherwise an error like this will be displayed: + > Error: creating EC2 Instance: OptInRequired: In order to use this AWS Marketplace product you need to accept terms and subscribe. To do so please visit https://aws.amazon.com/marketplace/pp?sku= + If this occurs, open the specific link from the error, while logged into the AWS account where Cloud Cluster will be deployed. Follow the instructions for subscribing to the product. + +## Changes + +Several variables have changed with this iteration of the script. Upgrades to existing deployments may cause unwanted changes. Be sure to check the changes of `terraform plan` before `terraform apply` to avoid disruptive behavior. ## How You Can Help We glady welcome contributions from the community. From updating the documentation to adding more functionality, all ideas are welcome. Thank you in advance for all of your issues, pull requests, and comments! diff --git a/docs/quick-start.md b/docs/quick-start.md index e5bf478..1525dfd 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -11,6 +11,7 @@ module "rubrik_aws_cloud_cluster" { source = "rubrikinc/rubrik-cloud-cluster/aws" aws_region = "us-west-1" + aws_subnet_id = "subnet-1234567890abcdefg" aws_ami_filter = ["rubrik-mp-cc-7*"] cluster_name = "rubrik-cloud-cluster" admin_email = "build@rubrik.com" @@ -104,34 +105,56 @@ This section outlines what is required to run the configuration defined above. ### Prerequisites -- [Terraform](https://www.terraform.io/downloads.html) v0.15.4 or greater +- [Terraform](https://www.terraform.io/downloads.html) v1.2.2 or greater - [Rubrik Provider for Terraform](https://github.com/rubrikinc/rubrik-provider-for-terraform) - provides Terraform functions for Rubrik - Only required to run the sample Rubrik Bootstrap command +- The Rubik Cloud Cluster product in the AWS Marketplace must be subscribed to. Otherwise an error like this will be displayed: + > Error: creating EC2 Instance: OptInRequired: In order to use this AWS Marketplace product you need to accept terms and subscribe. To do so please visit https://aws.amazon.com/marketplace/pp?sku= + + If this occurs, open the specific link from the error, while logged into the AWS account where Cloud Cluster will be deployed. Follow the instructions for subscribing to the product. ### Initialize the Directory The directory can be initialized for Terraform use by running the `terraform init` command: ```none +-> terraform init Initializing modules... -- module.rubrik_aws_cloud_cluster - Getting source "rubrikinc/aws-rubrik-cloud-cluster/module" +Downloading registry.terraform.io/terraform-aws-modules/key-pair/aws 1.0.1 for aws_key_pair... +- aws_key_pair in .terraform/modules/aws_key_pair +- cluster_nodes in modules/rubrik_aws_instances +- iam_role in modules/iam_role +Downloading registry.terraform.io/terraform-aws-modules/security-group/aws 4.9.0 for rubrik_hosts_sg... +- rubrik_hosts_sg in .terraform/modules/rubrik_hosts_sg +- rubrik_hosts_sg_rules in modules/rubrik_hosts_sg +Downloading registry.terraform.io/terraform-aws-modules/security-group/aws 4.9.0 for rubrik_hosts_sg_rules.this... +- rubrik_hosts_sg_rules.this in .terraform/modules/rubrik_hosts_sg_rules.this +Downloading registry.terraform.io/terraform-aws-modules/security-group/aws 4.9.0 for rubrik_nodes_sg... +- rubrik_nodes_sg in .terraform/modules/rubrik_nodes_sg +- rubrik_nodes_sg_rules in modules/rubrik_nodes_sg +Downloading registry.terraform.io/terraform-aws-modules/security-group/aws 4.9.0 for rubrik_nodes_sg_rules.this... +- rubrik_nodes_sg_rules.this in .terraform/modules/rubrik_nodes_sg_rules.this +Downloading registry.terraform.io/terraform-aws-modules/s3-bucket/aws 3.2.3 for s3_bucket... +- s3_bucket in .terraform/modules/s3_bucket +- s3_vpc_endpoint in modules/s3_vpc_endpoint +Downloading registry.terraform.io/terraform-aws-modules/vpc/aws 3.14.0 for s3_vpc_endpoint.endpoints... +- s3_vpc_endpoint.endpoints in .terraform/modules/s3_vpc_endpoint.endpoints/modules/vpc-endpoints + +Initializing the backend... Initializing provider plugins... -- Checking for available provider plugins on https://releases.hashicorp.com... -- Downloading plugin for provider "aws" (2.2.0)... -- Downloading plugin for provider "null" (2.1.0)... - -The following providers do not have any version constraints in configuration, -so the latest version was installed. - -To prevent automatic upgrades to new major versions that may contain breaking -changes, it is recommended to add version = "..." constraints to the -corresponding provider blocks in configuration, with the constraint strings -suggested below. - -* provider.aws: version = "~> 2.2" -* provider.null: version = "~> 2.1" +- Reusing previous version of hashicorp/tls from the dependency lock file +- Reusing previous version of hashicorp/local from the dependency lock file +- Reusing previous version of hashicorp/template from the dependency lock file +- Reusing previous version of hashicorp/aws from the dependency lock file +- Installing hashicorp/tls v3.4.0... +- Installed hashicorp/tls v3.4.0 (signed by HashiCorp) +- Installing hashicorp/local v2.2.3... +- Installed hashicorp/local v2.2.3 (signed by HashiCorp) +- Installing hashicorp/template v2.2.0... +- Installed hashicorp/template v2.2.0 (signed by HashiCorp) +- Installing hashicorp/aws v4.15.1... +- Installed hashicorp/aws v4.15.1 (signed by HashiCorp) Terraform has been successfully initialized! @@ -203,3 +226,29 @@ aws ec2 describe-images \ +--------------------------+-------------------------+-----------------------------------+ ``` +## Known issues + +There are a few known issues when using this Terraform module. These are described below. + +### Multiple existing S3 endpoints + +If there is already an S3 endpoint defined setting the variable `create_s3_vpc_endpoint` to `true` may cause the following error: + +> Error: multiple VPC Endpoints matched; use additional constraints to reduce matches to a single VPC Endpoint + +If this happens set teh `create_s3_vpc_endpoint` variable to `false`. Verify that the current VPC endpoint will be used by Rubrik Cloud Cluster, or add additional constraints to the `s3_vpc_endpoint` module in this Terraform. + +### Cloud Cluster ES now the default configuration + +With the 1.0 release of this Terraform module, Cloud Cluster ES is now the default configuration. As a result care should be taken to set the correct variables if classic Cloud Cluster is desired. + + ### Deploying Cloud Cluster from the AWS Marketplace requires subscription + +The Rubik product in the AWS Marketplace must be subscribed to. Otherwise an error like this will be displayed: +> Error: creating EC2 Instance: OptInRequired: In order to use this AWS Marketplace product you need to accept terms and subscribe. To do so please visit https://aws.amazon.com/marketplace/pp?sku= + +If this occurs, open the specific link from the error, while logged into the AWS account where Cloud Cluster will be deployed. Follow the instructions for subscribing to the product. + +### Variable name changes + +Several variables have changed with this iteration of the script. Upgrades to existing deployments may cause unwanted changes. Be sure to check the changes of `terraform plan` before `terraform apply` to avoid disruptive behavior. \ No newline at end of file From 5b494d5d0b3c383286dabcba91f39ceafc26f53c Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Mon, 6 Jun 2022 17:09:51 -0700 Subject: [PATCH 25/28] Fixed error when multple S3 endpoints are present --- docs/quick-start.md | 8 -------- main.tf | 6 +++++- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/quick-start.md b/docs/quick-start.md index 1525dfd..3a40f8f 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -230,14 +230,6 @@ aws ec2 describe-images \ There are a few known issues when using this Terraform module. These are described below. -### Multiple existing S3 endpoints - -If there is already an S3 endpoint defined setting the variable `create_s3_vpc_endpoint` to `true` may cause the following error: - -> Error: multiple VPC Endpoints matched; use additional constraints to reduce matches to a single VPC Endpoint - -If this happens set teh `create_s3_vpc_endpoint` variable to `false`. Verify that the current VPC endpoint will be used by Rubrik Cloud Cluster, or add additional constraints to the `s3_vpc_endpoint` module in this Terraform. - ### Cloud Cluster ES now the default configuration With the 1.0 release of this Terraform module, Cloud Cluster ES is now the default configuration. As a result care should be taken to set the correct variables if classic Cloud Cluster is desired. diff --git a/main.tf b/main.tf index c06b576..6499960 100644 --- a/main.tf +++ b/main.tf @@ -85,7 +85,11 @@ module "s3_vpc_endpoint" { create = var.create_s3_vpc_endpoint vpc_id = data.aws_subnet.rubrik_cloud_cluster.vpc_id - tags = var.aws_tags + + tags = merge( + { Name = "${var.cluster_name}:ep" }, + var.aws_tags + ) } ###################################################################### From f411a3c20b077373e59297235337590c47f292db Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Wed, 15 Jun 2022 13:52:29 -0700 Subject: [PATCH 26/28] Added support for AWS GovCloud --- cc_es_policy.json.tpl | 25 ------------------------- docs/quick-start.md | 28 +++++++++++++++++++++++++++- modules/iam_role/main.tf | 32 ++++++++++++++++++++++++-------- modules/iam_role/variables.tf | 2 +- variables.tf | 2 +- 5 files changed, 53 insertions(+), 36 deletions(-) delete mode 100644 cc_es_policy.json.tpl diff --git a/cc_es_policy.json.tpl b/cc_es_policy.json.tpl deleted file mode 100644 index c3eb893..0000000 --- a/cc_es_policy.json.tpl +++ /dev/null @@ -1,25 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "s3:AbortMultipartUpload", - "s3:DeleteObject*", - "s3:GetObject*", - "s3:ListMultipartUploadParts", - "s3:PutObject*" - ], - "Resource": "arn:aws:s3:::${resource}/*" - }, - { - "Effect": "Allow", - "Action": [ - "s3:GetBucket*", - "s3:ListBucket*" - ], - "Resource": "arn:aws:s3:::${resource}" - } - ] -} - diff --git a/docs/quick-start.md b/docs/quick-start.md index 3a40f8f..58f75c1 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -35,7 +35,7 @@ The following are the variables accepted by the module. | aws_disable_api_termination | If true, enables EC2 Instance Termination Protection on the Rubrik Cloud Cluster nodes. | bool | true | no | | aws_tags | Tags to add to the resources that this Terraform script creates, including the Rubrik cluster nodes. | map | | no | | number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 3 | no | -| aws_ami_owners | AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs. | list | ["679593333241"] | no | +| aws_ami_owners | AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs. Use [\"345084742485\"] for AWS GovCloud. | list | ["679593333241"] | no | | aws_ami_filter | Cloud Cluster AWS AMI name pattern(s) to search for. Use [\"rubrik-mp-cc-*\"]. Where is the major version of CDM. | list | | yes | | aws_image_id | AWS Image ID to deploy. Set to 'latest' or leave blank to deploy the latest version as determined by `aws_ami_filter`. | string | latest | no | | create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | @@ -225,6 +225,31 @@ aws ec2 describe-images \ | 2022-05-26T19:08:31.000Z| ami-04d6af7c6f6629ce1 | Rubrik OS rubrik-7-0-2-15510 | +--------------------------+-------------------------+-----------------------------------+ ``` +For AWS Gov cloud change the `owner-id` to `345084742485`. + +Example: + +```none +aws ec2 describe-images \ + --filters 'Name=owner-id,Values=345084742485' 'Name=name,Values=rubrik-mp-cc-7*' \ + --query 'sort_by(Images, &CreationDate)[*].{"Create Date":CreationDate, "Image ID":ImageId, Version:Description}' \ + --region 'us-gov-west-1' \ + --output table + +------------------------------------------------------------------------------------------ +| DescribeImages | ++--------------------------+-------------------------+-----------------------------------+ +| Create Date | Image ID | Version | ++--------------------------+-------------------------+-----------------------------------+ +| 2022-01-27T09:17:44.000Z| ami-038cb33e356dfdb84 | Rubrik OS rubrik-7-0-0-14706 | +| 2022-02-05T20:14:25.000Z| ami-09c62e5a399fc5526 | Rubrik OS rubrik-7-0-0-14764 | +| 2022-04-01T22:44:52.000Z| ami-0852636d1bb4376a9 | Rubrik OS rubrik-7-0-1-15183 | +| 2022-04-13T03:06:33.000Z| ami-0e77ba2b8cdeb645c | Rubrik OS rubrik-7-0-1-p1-15197 | +| 2022-04-28T04:54:07.000Z| ami-0486bfdcbf4ee6d5e | Rubrik OS rubrik-7-0-1-p2-15336 | +| 2022-05-14T19:53:12.000Z| ami-0b519a90ae467950d | Rubrik OS rubrik-7-0-1-p3-15425 | +| 2022-05-20T23:18:12.000Z| ami-060706f9a9462b5e7 | Rubrik OS rubrik-7-0-1-p4-15453 | ++--------------------------+-------------------------+-----------------------------------+ +``` ## Known issues @@ -240,6 +265,7 @@ The Rubik product in the AWS Marketplace must be subscribed to. Otherwise an err > Error: creating EC2 Instance: OptInRequired: In order to use this AWS Marketplace product you need to accept terms and subscribe. To do so please visit https://aws.amazon.com/marketplace/pp?sku= If this occurs, open the specific link from the error, while logged into the AWS account where Cloud Cluster will be deployed. Follow the instructions for subscribing to the product. +For AWS GovCloud the link points to the public marketplace. Instead of following the link, launch one instance of the major version of Rubrik from the AWS console. This will accept the terms and subscribe to the subscription. Remove the manually launched instance and then run the Terraform again. ### Variable name changes diff --git a/modules/iam_role/main.tf b/modules/iam_role/main.tf index 0af73be..8936fc0 100644 --- a/modules/iam_role/main.tf +++ b/modules/iam_role/main.tf @@ -1,10 +1,3 @@ -data "template_file" "aws_iam_role_policy" { - template = file("cc_es_policy.json.tpl") - vars = { - resource = var.bucket - } -} - resource "aws_iam_role" "rubrik_ec2_s3" { count = var.create ? 1 : 0 @@ -30,7 +23,30 @@ resource "aws_iam_role_policy" "rubrik_ec2_s3_policy" { count = var.create ? 1 : 0 name = var.role_policy_name role = aws_iam_role.rubrik_ec2_s3[0].name - policy = data.template_file.aws_iam_role_policy.rendered + policy = jsonencode ({ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:AbortMultipartUpload", + "s3:DeleteObject*", + "s3:GetObject*", + "s3:ListMultipartUploadParts", + "s3:PutObject*" + ], + "Resource": "${var.bucket.s3_bucket_arn}/*" + }, + { + "Effect": "Allow", + "Action": [ + "s3:GetBucket*", + "s3:ListBucket*" + ], + "Resource": "${var.bucket.s3_bucket_arn}" + } + ] + }) } resource "aws_iam_instance_profile" "rubrik_ec2_s3_profile" { diff --git a/modules/iam_role/variables.tf b/modules/iam_role/variables.tf index cb80613..91018c8 100644 --- a/modules/iam_role/variables.tf +++ b/modules/iam_role/variables.tf @@ -1,5 +1,5 @@ variable "bucket" { - type = string + type = map(any) } variable "create" { diff --git a/variables.tf b/variables.tf index acd1e49..8b6e2ab 100644 --- a/variables.tf +++ b/variables.tf @@ -25,7 +25,7 @@ variable "number_of_nodes" { } variable "aws_ami_owners" { - description = "AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs." + description = "AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs. Use [\"345084742485\"] for AWS GovCloud." type = set(string) default = ["679593333241"] } From 6608f042650a9ed638a93fb521bf093395238d6f Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Wed, 15 Jun 2022 14:32:51 -0700 Subject: [PATCH 27/28] Fix issue when not creating a VPC endpoint. --- modules/s3_vpc_endpoint/main.tf | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/modules/s3_vpc_endpoint/main.tf b/modules/s3_vpc_endpoint/main.tf index 5ca7eda..d123041 100644 --- a/modules/s3_vpc_endpoint/main.tf +++ b/modules/s3_vpc_endpoint/main.tf @@ -1,29 +1,22 @@ +locals { + get_endpoint_data = var.create == true ? 1 : 0 +} data "aws_region" "current" {} -module "endpoints" { - source = "terraform-aws-modules/vpc/aws//modules/vpc-endpoints" - - vpc_id = var.vpc_id - create = var.create - - endpoints = { - s3 = { - # gateway endpoint - service = "s3" - tags = var.tags - route_table_ids = var.route_table_ids - service_type = "Gateway" - - } - } +resource "aws_vpc_endpoint" "s3_endpoint" { + count = local.get_endpoint_data + vpc_id = var.vpc_id + service_name = "com.amazonaws.${data.aws_region.current.id}.s3" + vpc_endpoint_type = "Gateway" tags = var.tags } data "aws_vpc_endpoint" "this" { + count = local.get_endpoint_data vpc_id = var.vpc_id - service_name = "com.amazonaws.${data.aws_region.current.name}.s3" + id = aws_vpc_endpoint.s3_endpoint[0].id depends_on = [ - module.endpoints + aws_vpc_endpoint.s3_endpoint ] } \ No newline at end of file From 9be72851a55371a79c85d204658a688fe7528758 Mon Sep 17 00:00:00 2001 From: DamaniN <37876601+DamaniN@users.noreply.github.com> Date: Wed, 15 Jun 2022 13:52:29 -0700 Subject: [PATCH 28/28] Added support for AWS GovCloud --- cc_es_policy.json.tpl | 25 ------------------------- docs/quick-start.md | 28 +++++++++++++++++++++++++++- main.tf | 2 +- modules/iam_role/main.tf | 32 ++++++++++++++++++++++++-------- modules/iam_role/variables.tf | 2 +- variables.tf | 2 +- 6 files changed, 54 insertions(+), 37 deletions(-) delete mode 100644 cc_es_policy.json.tpl diff --git a/cc_es_policy.json.tpl b/cc_es_policy.json.tpl deleted file mode 100644 index c3eb893..0000000 --- a/cc_es_policy.json.tpl +++ /dev/null @@ -1,25 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "s3:AbortMultipartUpload", - "s3:DeleteObject*", - "s3:GetObject*", - "s3:ListMultipartUploadParts", - "s3:PutObject*" - ], - "Resource": "arn:aws:s3:::${resource}/*" - }, - { - "Effect": "Allow", - "Action": [ - "s3:GetBucket*", - "s3:ListBucket*" - ], - "Resource": "arn:aws:s3:::${resource}" - } - ] -} - diff --git a/docs/quick-start.md b/docs/quick-start.md index 3a40f8f..58f75c1 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -35,7 +35,7 @@ The following are the variables accepted by the module. | aws_disable_api_termination | If true, enables EC2 Instance Termination Protection on the Rubrik Cloud Cluster nodes. | bool | true | no | | aws_tags | Tags to add to the resources that this Terraform script creates, including the Rubrik cluster nodes. | map | | no | | number_of_nodes | The total number of nodes in Rubrik Cloud Cluster. | int | 3 | no | -| aws_ami_owners | AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs. | list | ["679593333241"] | no | +| aws_ami_owners | AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs. Use [\"345084742485\"] for AWS GovCloud. | list | ["679593333241"] | no | | aws_ami_filter | Cloud Cluster AWS AMI name pattern(s) to search for. Use [\"rubrik-mp-cc-*\"]. Where is the major version of CDM. | list | | yes | | aws_image_id | AWS Image ID to deploy. Set to 'latest' or leave blank to deploy the latest version as determined by `aws_ami_filter`. | string | latest | no | | create_key_pair | If true, a new AWS SSH Key-Pair will be created using the aws_key_pair_name and aws_public_key settings. | bool | true | no | @@ -225,6 +225,31 @@ aws ec2 describe-images \ | 2022-05-26T19:08:31.000Z| ami-04d6af7c6f6629ce1 | Rubrik OS rubrik-7-0-2-15510 | +--------------------------+-------------------------+-----------------------------------+ ``` +For AWS Gov cloud change the `owner-id` to `345084742485`. + +Example: + +```none +aws ec2 describe-images \ + --filters 'Name=owner-id,Values=345084742485' 'Name=name,Values=rubrik-mp-cc-7*' \ + --query 'sort_by(Images, &CreationDate)[*].{"Create Date":CreationDate, "Image ID":ImageId, Version:Description}' \ + --region 'us-gov-west-1' \ + --output table + +------------------------------------------------------------------------------------------ +| DescribeImages | ++--------------------------+-------------------------+-----------------------------------+ +| Create Date | Image ID | Version | ++--------------------------+-------------------------+-----------------------------------+ +| 2022-01-27T09:17:44.000Z| ami-038cb33e356dfdb84 | Rubrik OS rubrik-7-0-0-14706 | +| 2022-02-05T20:14:25.000Z| ami-09c62e5a399fc5526 | Rubrik OS rubrik-7-0-0-14764 | +| 2022-04-01T22:44:52.000Z| ami-0852636d1bb4376a9 | Rubrik OS rubrik-7-0-1-15183 | +| 2022-04-13T03:06:33.000Z| ami-0e77ba2b8cdeb645c | Rubrik OS rubrik-7-0-1-p1-15197 | +| 2022-04-28T04:54:07.000Z| ami-0486bfdcbf4ee6d5e | Rubrik OS rubrik-7-0-1-p2-15336 | +| 2022-05-14T19:53:12.000Z| ami-0b519a90ae467950d | Rubrik OS rubrik-7-0-1-p3-15425 | +| 2022-05-20T23:18:12.000Z| ami-060706f9a9462b5e7 | Rubrik OS rubrik-7-0-1-p4-15453 | ++--------------------------+-------------------------+-----------------------------------+ +``` ## Known issues @@ -240,6 +265,7 @@ The Rubik product in the AWS Marketplace must be subscribed to. Otherwise an err > Error: creating EC2 Instance: OptInRequired: In order to use this AWS Marketplace product you need to accept terms and subscribe. To do so please visit https://aws.amazon.com/marketplace/pp?sku= If this occurs, open the specific link from the error, while logged into the AWS account where Cloud Cluster will be deployed. Follow the instructions for subscribing to the product. +For AWS GovCloud the link points to the public marketplace. Instead of following the link, launch one instance of the major version of Rubrik from the AWS console. This will accept the terms and subscribe to the subscription. Remove the manually launched instance and then run the Terraform again. ### Variable name changes diff --git a/main.tf b/main.tf index 6499960..d804391 100644 --- a/main.tf +++ b/main.tf @@ -171,7 +171,7 @@ module "s3_bucket" { module "iam_role" { source = "./modules/iam_role" - bucket = module.s3_bucket.s3_bucket_id + bucket = module.s3_bucket create = var.create_iam_role role_name = var.aws_cloud_cluster_iam_role_name == "" ? "${var.cluster_name}.role" : var.aws_cloud_cluster_iam_role_name role_policy_name = var.aws_cloud_cluster_iam_role_policy_name == "" ? "${var.cluster_name}.role-policy" : var.aws_cloud_cluster_iam_role_policy_name diff --git a/modules/iam_role/main.tf b/modules/iam_role/main.tf index 0af73be..8936fc0 100644 --- a/modules/iam_role/main.tf +++ b/modules/iam_role/main.tf @@ -1,10 +1,3 @@ -data "template_file" "aws_iam_role_policy" { - template = file("cc_es_policy.json.tpl") - vars = { - resource = var.bucket - } -} - resource "aws_iam_role" "rubrik_ec2_s3" { count = var.create ? 1 : 0 @@ -30,7 +23,30 @@ resource "aws_iam_role_policy" "rubrik_ec2_s3_policy" { count = var.create ? 1 : 0 name = var.role_policy_name role = aws_iam_role.rubrik_ec2_s3[0].name - policy = data.template_file.aws_iam_role_policy.rendered + policy = jsonencode ({ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:AbortMultipartUpload", + "s3:DeleteObject*", + "s3:GetObject*", + "s3:ListMultipartUploadParts", + "s3:PutObject*" + ], + "Resource": "${var.bucket.s3_bucket_arn}/*" + }, + { + "Effect": "Allow", + "Action": [ + "s3:GetBucket*", + "s3:ListBucket*" + ], + "Resource": "${var.bucket.s3_bucket_arn}" + } + ] + }) } resource "aws_iam_instance_profile" "rubrik_ec2_s3_profile" { diff --git a/modules/iam_role/variables.tf b/modules/iam_role/variables.tf index cb80613..91018c8 100644 --- a/modules/iam_role/variables.tf +++ b/modules/iam_role/variables.tf @@ -1,5 +1,5 @@ variable "bucket" { - type = string + type = map(any) } variable "create" { diff --git a/variables.tf b/variables.tf index acd1e49..8b6e2ab 100644 --- a/variables.tf +++ b/variables.tf @@ -25,7 +25,7 @@ variable "number_of_nodes" { } variable "aws_ami_owners" { - description = "AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs." + description = "AWS marketplace account(s) that owns the Rubrik Cloud Cluster AMIs. Use [\"345084742485\"] for AWS GovCloud." type = set(string) default = ["679593333241"] }