diff options
Diffstat (limited to 'fdio.infra.terraform')
198 files changed, 12778 insertions, 0 deletions
diff --git a/fdio.infra.terraform/.gitignore b/fdio.infra.terraform/.gitignore new file mode 100644 index 0000000000..223f2ec48c --- /dev/null +++ b/fdio.infra.terraform/.gitignore @@ -0,0 +1,36 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* +.terraform.lock.hcl +.terraform.tfstate.lock.info + +# Crash log files +crash.log + +# Exclude all .tfvars files, which are likely to contain sentitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +# +*.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-1n-aws-c5n/hosts.tftpl b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/hosts.tftpl new file mode 100644 index 0000000000..58594efe9d --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/hosts.tftpl @@ -0,0 +1,5 @@ +all: + children: + tg: + hosts: + ${tg_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-1n-aws-c5n/main.tf b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/main.tf new file mode 100644 index 0000000000..e455b6b104 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/main.tf @@ -0,0 +1,211 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "eu-central-1a" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "1n-aws-c5n" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "local_file" "topology_file" { + depends_on = [ + aws_instance.tg + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + } + ) + filename = "${path.module}/../../topologies/available/${local.topology_name}-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + aws_instance.tg + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = aws_instance.tg.public_ip + } + ) + filename = "${path.module}/../../fdio.infra.ansible/inventories/cloud_inventory/hosts.yaml" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-1n-aws-c5n/output.tf b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/output.tf diff --git a/fdio.infra.terraform/terraform-aws-1n-aws-c5n/providers.tf b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/providers.tf new file mode 100644 index 0000000000..2482ca2839 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://10.30.51.24:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-1n-aws-c5n/topology-1n-aws-c5n.tftpl b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/topology-1n-aws-c5n.tftpl new file mode 100644 index 0000000000..c99d1f5ebc --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/topology-1n-aws-c5n.tftpl @@ -0,0 +1,30 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/1_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 1-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 50GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-50G + port2: + # tg_instance/p2 - 50GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link1 + model: Amazon-Nitro-50G
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-1n-aws-c5n/variables.tf b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/variables.tf new file mode 100644 index 0000000000..566a073266 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/variables.tf @@ -0,0 +1,120 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-central-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-1n-aws-c5n" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "ED25519" +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07430bfa17fd4e597" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c5n.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/16" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/16" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-1n-aws-c5n/versions.tf b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/versions.tf new file mode 100644 index 0000000000..7e17bb4924 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-aws-c5n/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +} diff --git a/fdio.infra.terraform/terraform-aws-1n-c6in/hosts.tftpl b/fdio.infra.terraform/terraform-aws-1n-c6in/hosts.tftpl new file mode 100644 index 0000000000..58594efe9d --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-c6in/hosts.tftpl @@ -0,0 +1,5 @@ +all: + children: + tg: + hosts: + ${tg_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-1n-c6in/main.tf b/fdio.infra.terraform/terraform-aws-1n-c6in/main.tf new file mode 100644 index 0000000000..94cac297c2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-c6in/main.tf @@ -0,0 +1,206 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "eu-central-1b" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "1n-c6in" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + + +resource "null_resource" "deploy_topology" { + depends_on = [ + aws_instance.tg + ] + + provisioner "ansible" { + plays { + playbook { + file_path = var.ansible_topology_path + } + hosts = ["local"] + extra_vars = { + ansible_python_interpreter = local.ansible_python_executable + testbed_name = local.testbed_name + cloud_topology = local.topology_name + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + public_ip_list = "${aws_instance.tg.public_ip}" + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-1n-c6in/output.tf b/fdio.infra.terraform/terraform-aws-1n-c6in/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-c6in/output.tf diff --git a/fdio.infra.terraform/terraform-aws-1n-c6in/providers.tf b/fdio.infra.terraform/terraform-aws-1n-c6in/providers.tf new file mode 100644 index 0000000000..2482ca2839 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-c6in/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://10.30.51.24:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-1n-c6in/topology-1n-c6in.tftpl b/fdio.infra.terraform/terraform-aws-1n-c6in/topology-1n-c6in.tftpl new file mode 100644 index 0000000000..dc24577bbd --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-c6in/topology-1n-c6in.tftpl @@ -0,0 +1,30 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/1_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 1-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 200GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-200G + port2: + # tg_instance/p2 - 200GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link1 + model: Amazon-Nitro-200G
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-1n-c6in/variables.tf b/fdio.infra.terraform/terraform-aws-1n-c6in/variables.tf new file mode 100644 index 0000000000..db0cfa89da --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-c6in/variables.tf @@ -0,0 +1,120 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-central-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-1n-c6in" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "ED25519" +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07430bfa17fd4e597" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/16" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/16" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-1n-c6in/versions.tf b/fdio.infra.terraform/terraform-aws-1n-c6in/versions.tf new file mode 100644 index 0000000000..7e17bb4924 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-1n-c6in/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +} diff --git a/fdio.infra.terraform/terraform-aws-2n-aws-c5n/hosts.tftpl b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/hosts.tftpl new file mode 100644 index 0000000000..cb36dbb138 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/hosts.tftpl @@ -0,0 +1,8 @@ +all: + children: + tg: + hosts: + ${tg_public_ip} + sut: + hosts: + ${dut1_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-aws-c5n/main.tf b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/main.tf new file mode 100644 index 0000000000..a7abab1214 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/main.tf @@ -0,0 +1,335 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "eu-central-1a" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "2n-aws-c5n" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + vpc_enable_dns_hostnames = false +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_d" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.20.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 4) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ip = var.tg_if1_private_ip + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_d, + aws_instance.tg + ] + private_ip = var.tg_if2_private_ip + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_instance" "sut1" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut1_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut1_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut1_instance_initiated_shutdown_behavior + instance_type = var.sut1_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut1_private_ip + source_dest_check = var.sut1_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if1" { + depends_on = [ + module.subnet_b, + aws_instance.sut1 + ] + private_ip = var.sut1_if1_private_ip + private_ips = [var.sut1_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 1 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if2" { + depends_on = [ + module.subnet_d, + aws_instance.sut1 + ] + private_ip = var.sut1_if2_private_ip + private_ips = [var.sut1_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 2 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut1_if1" { + id = aws_network_interface.sut1_if1.id +} + +data "aws_network_interface" "sut1_if2" { + id = aws_network_interface.sut1_if2.id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut1" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut1.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "local_file" "topology_file" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1 + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + dut1_if1_mac = data.aws_network_interface.sut1_if1.mac_address + dut1_if2_mac = data.aws_network_interface.sut1_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + } + ) + filename = "${path.module}/../../topologies/available/${local.topology_name}-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1 + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + } + ) + filename = "${path.module}/../../fdio.infra.ansible/inventories/cloud_inventory/hosts.yaml" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-aws-c5n/output.tf b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/output.tf diff --git a/fdio.infra.terraform/terraform-aws-2n-aws-c5n/providers.tf b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/providers.tf new file mode 100644 index 0000000000..2482ca2839 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://10.30.51.24:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-aws-c5n/topology-2n-aws-c5n.tftpl b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/topology-2n-aws-c5n.tftpl new file mode 100644 index 0000000000..313b4b3d86 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/topology-2n-aws-c5n.tftpl @@ -0,0 +1,51 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/2_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 2-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 50GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-50G + port2: + # tg_instance/p2 - 50GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-50G + DUT1: + type: DUT + host: ${dut1_public_ip} + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut1_instance/p1 - 50GE port1 on ENA NIC. + mac_address: "${dut1_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-50G + port2: + # dut1_instance/p2 - 50GE port2 on ENA NIC. + mac_address: "${dut1_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-50G
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-aws-c5n/variables.tf b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/variables.tf new file mode 100644 index 0000000000..de113166e6 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/variables.tf @@ -0,0 +1,168 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-central-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-2n-aws-c5n" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "ED25519" +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07430bfa17fd4e597" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c5n.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut1_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-0a890555652963ec2" +} + +variable "sut1_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut1_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut1_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c5n.4xlarge" +} + +variable "sut1_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.11" +} + +variable "sut1_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.254" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/24" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/24" +} + +variable "sut1_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "sut1_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.11" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-2n-aws-c5n/versions.tf b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/versions.tf new file mode 100644 index 0000000000..589699691e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-aws-c5n/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6gn/hosts.tftpl b/fdio.infra.terraform/terraform-aws-2n-c6gn/hosts.tftpl new file mode 100644 index 0000000000..cb36dbb138 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6gn/hosts.tftpl @@ -0,0 +1,8 @@ +all: + children: + tg: + hosts: + ${tg_public_ip} + sut: + hosts: + ${dut1_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6gn/main.tf b/fdio.infra.terraform/terraform-aws-2n-c6gn/main.tf new file mode 100644 index 0000000000..b3da06ba76 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6gn/main.tf @@ -0,0 +1,335 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "eu-central-1a" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "2n-c6gn" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + vpc_enable_dns_hostnames = false +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_d" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.20.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 4) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ip = var.tg_if1_private_ip + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_d, + aws_instance.tg + ] + private_ip = var.tg_if2_private_ip + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_instance" "sut1" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut1_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut1_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut1_instance_initiated_shutdown_behavior + instance_type = var.sut1_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut1_private_ip + source_dest_check = var.sut1_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if1" { + depends_on = [ + module.subnet_b, + aws_instance.sut1 + ] + private_ip = var.sut1_if1_private_ip + private_ips = [var.sut1_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 1 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if2" { + depends_on = [ + module.subnet_d, + aws_instance.sut1 + ] + private_ip = var.sut1_if2_private_ip + private_ips = [var.sut1_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 2 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut1_if1" { + id = aws_network_interface.sut1_if1.id +} + +data "aws_network_interface" "sut1_if2" { + id = aws_network_interface.sut1_if2.id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut1" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut1.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "local_file" "topology_file" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1 + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + dut1_if1_mac = data.aws_network_interface.sut1_if1.mac_address + dut1_if2_mac = data.aws_network_interface.sut1_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + } + ) + filename = "${path.module}/../../topologies/available/${local.topology_name}-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1 + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + } + ) + filename = "${path.module}/../../fdio.infra.ansible/inventories/cloud_inventory/hosts.yaml" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6gn/output.tf b/fdio.infra.terraform/terraform-aws-2n-c6gn/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6gn/output.tf diff --git a/fdio.infra.terraform/terraform-aws-2n-c6gn/providers.tf b/fdio.infra.terraform/terraform-aws-2n-c6gn/providers.tf new file mode 100644 index 0000000000..d0e7490d38 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6gn/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://vault.service.consul:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6gn/topology-2n-c6gn.tftpl b/fdio.infra.terraform/terraform-aws-2n-c6gn/topology-2n-c6gn.tftpl new file mode 100644 index 0000000000..a0fa5fc191 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6gn/topology-2n-c6gn.tftpl @@ -0,0 +1,51 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/2_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 2-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-100G + port2: + # tg_instance/p2 - 100GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-100G + DUT1: + type: DUT + host: "${dut1_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut1_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${dut1_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-100G + port2: + # dut1_instance/p2 - 100GE port2 on ENA NIC. + mac_address: "${dut1_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-100G
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6gn/variables.tf b/fdio.infra.terraform/terraform-aws-2n-c6gn/variables.tf new file mode 100644 index 0000000000..fec833126d --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6gn/variables.tf @@ -0,0 +1,180 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-central-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-2n-c6gn" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "RSA" +} + +variable "private_key_ecdsa_curve" { + description = "When algorithm is ECDSA, the name of the elliptic curve to use." + type = string + default = "P521" +} + +variable "private_key_rsa_bits" { + description = "When algorithm is RSA, the size of the generated RSA key in bits." + type = number + default = 4096 +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07430bfa17fd4e597" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut1_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-0cebabdc14ee56909" +} + +variable "sut1_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut1_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut1_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6gn.4xlarge" +} + +variable "sut1_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.11" +} + +variable "sut1_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.254" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/24" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/24" +} + +variable "sut1_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "sut1_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.11" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-2n-c6gn/versions.tf b/fdio.infra.terraform/terraform-aws-2n-c6gn/versions.tf new file mode 100644 index 0000000000..589699691e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6gn/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6in/hosts.tftpl b/fdio.infra.terraform/terraform-aws-2n-c6in/hosts.tftpl new file mode 100644 index 0000000000..cb36dbb138 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6in/hosts.tftpl @@ -0,0 +1,8 @@ +all: + children: + tg: + hosts: + ${tg_public_ip} + sut: + hosts: + ${dut1_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6in/main.tf b/fdio.infra.terraform/terraform-aws-2n-c6in/main.tf new file mode 100644 index 0000000000..5edeb46ba2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6in/main.tf @@ -0,0 +1,335 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "eu-central-1b" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "2n-c6in" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + vpc_enable_dns_hostnames = false +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_d" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.20.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 4) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ip = var.tg_if1_private_ip + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_d, + aws_instance.tg + ] + private_ip = var.tg_if2_private_ip + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_instance" "sut1" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut1_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut1_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut1_instance_initiated_shutdown_behavior + instance_type = var.sut1_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut1_private_ip + source_dest_check = var.sut1_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if1" { + depends_on = [ + module.subnet_b, + aws_instance.sut1 + ] + private_ip = var.sut1_if1_private_ip + private_ips = [var.sut1_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 1 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if2" { + depends_on = [ + module.subnet_d, + aws_instance.sut1 + ] + private_ip = var.sut1_if2_private_ip + private_ips = [var.sut1_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 2 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut1_if1" { + id = aws_network_interface.sut1_if1.id +} + +data "aws_network_interface" "sut1_if2" { + id = aws_network_interface.sut1_if2.id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut1" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut1.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "local_file" "topology_file" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1 + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + dut1_if1_mac = data.aws_network_interface.sut1_if1.mac_address + dut1_if2_mac = data.aws_network_interface.sut1_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + } + ) + filename = "${path.module}/../../topologies/available/${local.topology_name}-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1 + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + } + ) + filename = "${path.module}/../../fdio.infra.ansible/inventories/cloud_inventory/hosts.yaml" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6in/output.tf b/fdio.infra.terraform/terraform-aws-2n-c6in/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6in/output.tf diff --git a/fdio.infra.terraform/terraform-aws-2n-c6in/providers.tf b/fdio.infra.terraform/terraform-aws-2n-c6in/providers.tf new file mode 100644 index 0000000000..d0e7490d38 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6in/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://vault.service.consul:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6in/topology-2n-c6in.tftpl b/fdio.infra.terraform/terraform-aws-2n-c6in/topology-2n-c6in.tftpl new file mode 100644 index 0000000000..d012d335b6 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6in/topology-2n-c6in.tftpl @@ -0,0 +1,51 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/2_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 2-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 200GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-200G + port2: + # tg_instance/p2 - 200GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-200G + DUT1: + type: DUT + host: ${dut1_public_ip} + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut1_instance/p1 - 200GE port1 on ENA NIC. + mac_address: "${dut1_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-200G + port2: + # dut1_instance/p2 - 200GE port2 on ENA NIC. + mac_address: "${dut1_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-200G
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c6in/variables.tf b/fdio.infra.terraform/terraform-aws-2n-c6in/variables.tf new file mode 100644 index 0000000000..51af9587d9 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6in/variables.tf @@ -0,0 +1,180 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-central-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-2n-c6in" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "RSA" +} + +variable "private_key_ecdsa_curve" { + description = "When algorithm is ECDSA, the name of the elliptic curve to use." + type = string + default = "P521" +} + +variable "private_key_rsa_bits" { + description = "When algorithm is RSA, the size of the generated RSA key in bits." + type = number + default = 4096 +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07430bfa17fd4e597" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut1_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-0a890555652963ec2" +} + +variable "sut1_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut1_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut1_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "sut1_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.11" +} + +variable "sut1_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.254" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/24" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/24" +} + +variable "sut1_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "sut1_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.11" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-2n-c6in/versions.tf b/fdio.infra.terraform/terraform-aws-2n-c6in/versions.tf new file mode 100644 index 0000000000..589699691e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c6in/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c7gn/hosts.tftpl b/fdio.infra.terraform/terraform-aws-2n-c7gn/hosts.tftpl new file mode 100644 index 0000000000..cb36dbb138 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c7gn/hosts.tftpl @@ -0,0 +1,8 @@ +all: + children: + tg: + hosts: + ${tg_public_ip} + sut: + hosts: + ${dut1_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c7gn/main.tf b/fdio.infra.terraform/terraform-aws-2n-c7gn/main.tf new file mode 100644 index 0000000000..5d9899773b --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c7gn/main.tf @@ -0,0 +1,335 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "${var.region}a" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "2n-c7gn" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + vpc_enable_dns_hostnames = false +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_d" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.20.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 4) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ip = var.tg_if1_private_ip + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_d, + aws_instance.tg + ] + private_ip = var.tg_if2_private_ip + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_instance" "sut1" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut1_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut1_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut1_instance_initiated_shutdown_behavior + instance_type = var.sut1_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut1_private_ip + source_dest_check = var.sut1_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if1" { + depends_on = [ + module.subnet_b, + aws_instance.sut1 + ] + private_ip = var.sut1_if1_private_ip + private_ips = [var.sut1_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 1 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if2" { + depends_on = [ + module.subnet_d, + aws_instance.sut1 + ] + private_ip = var.sut1_if2_private_ip + private_ips = [var.sut1_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 2 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut1_if1" { + id = aws_network_interface.sut1_if1.id +} + +data "aws_network_interface" "sut1_if2" { + id = aws_network_interface.sut1_if2.id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut1" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut1.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "local_file" "topology_file" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1 + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + dut1_if1_mac = data.aws_network_interface.sut1_if1.mac_address + dut1_if2_mac = data.aws_network_interface.sut1_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + } + ) + filename = "${path.module}/../../topologies/available/${local.topology_name}-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1 + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + } + ) + filename = "${path.module}/../../fdio.infra.ansible/inventories/cloud_inventory/hosts.yaml" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c7gn/output.tf b/fdio.infra.terraform/terraform-aws-2n-c7gn/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c7gn/output.tf diff --git a/fdio.infra.terraform/terraform-aws-2n-c7gn/providers.tf b/fdio.infra.terraform/terraform-aws-2n-c7gn/providers.tf new file mode 100644 index 0000000000..d0e7490d38 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c7gn/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://vault.service.consul:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c7gn/topology-2n-c7gn.tftpl b/fdio.infra.terraform/terraform-aws-2n-c7gn/topology-2n-c7gn.tftpl new file mode 100644 index 0000000000..a0fa5fc191 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c7gn/topology-2n-c7gn.tftpl @@ -0,0 +1,51 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/2_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 2-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-100G + port2: + # tg_instance/p2 - 100GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-100G + DUT1: + type: DUT + host: "${dut1_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut1_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${dut1_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-100G + port2: + # dut1_instance/p2 - 100GE port2 on ENA NIC. + mac_address: "${dut1_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-100G
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-2n-c7gn/variables.tf b/fdio.infra.terraform/terraform-aws-2n-c7gn/variables.tf new file mode 100644 index 0000000000..2a80b86936 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c7gn/variables.tf @@ -0,0 +1,168 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-west-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-2n-c7gn" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "ED25519" +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-0b5aa26a6e4192705" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut1_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-08930f71bd0be1085" +} + +variable "sut1_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut1_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut1_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c7gn.4xlarge" +} + +variable "sut1_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.11" +} + +variable "sut1_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.254" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/24" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/24" +} + +variable "sut1_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "sut1_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.11" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-2n-c7gn/versions.tf b/fdio.infra.terraform/terraform-aws-2n-c7gn/versions.tf new file mode 100644 index 0000000000..589699691e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-2n-c7gn/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-aws-c5n/hosts.tftpl b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/hosts.tftpl new file mode 100644 index 0000000000..e88c8ba510 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/hosts.tftpl @@ -0,0 +1,9 @@ +all: + children: + tg: + hosts: + ${tg_public_ip} + sut: + hosts: + ${dut1_public_ip} + ${dut2_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-aws-c5n/main.tf b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/main.tf new file mode 100644 index 0000000000..c95c8a6588 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/main.tf @@ -0,0 +1,457 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "eu-central-1a" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "3n-aws-c5n" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" + sut2_name = "${var.resource_prefix}-${var.testbed_name}-sut2" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_c" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "200.0.0.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 3) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_d" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.20.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 4) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ip = var.tg_if1_private_ip + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_d, + aws_instance.tg + ] + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_instance" "sut1" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut1_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut1_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut1_instance_initiated_shutdown_behavior + instance_type = var.sut1_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut1_private_ip + source_dest_check = var.sut1_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if1" { + depends_on = [ + module.subnet_b, + aws_instance.sut1 + ] + private_ips = [var.sut1_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 1 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if2" { + depends_on = [ + module.subnet_c, + aws_instance.sut1 + ] + private_ips = [var.sut1_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_c.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 2 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut1_if1" { + id = aws_network_interface.sut1_if1.id +} + +data "aws_network_interface" "sut1_if2" { + id = aws_network_interface.sut1_if2.id +} + +resource "aws_instance" "sut2" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut2_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut2_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut2_instance_initiated_shutdown_behavior + instance_type = var.sut2_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut2_private_ip + source_dest_check = var.sut2_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut2_if1" { + depends_on = [ + module.subnet_c, + aws_instance.sut2 + ] + private_ips = [var.sut2_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut2_source_dest_check + subnet_id = module.subnet_c.subnet_id + + attachment { + instance = aws_instance.sut2.id + device_index = 1 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut2_if2" { + depends_on = [ + module.subnet_d, + aws_instance.sut2 + ] + private_ips = [var.sut2_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut2_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.sut2.id + device_index = 2 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut2_if1" { + id = aws_network_interface.sut2_if1.id +} + +data "aws_network_interface" "sut2_if2" { + id = aws_network_interface.sut2_if2.id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut1" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut1.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut2" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut2.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "local_file" "topology_file" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1, + aws_instance.sut2 + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + dut1_if1_mac = data.aws_network_interface.sut1_if1.mac_address + dut1_if2_mac = data.aws_network_interface.sut1_if2.mac_address + dut2_if1_mac = data.aws_network_interface.sut2_if1.mac_address + dut2_if2_mac = data.aws_network_interface.sut2_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + dut2_public_ip = aws_instance.sut2.public_ip + } + ) + filename = "${path.module}/../../topologies/available/${local.topology_name}-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1, + aws_instance.sut2 + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + dut2_public_ip = aws_instance.sut2.public_ip + } + ) + filename = "${path.module}/../../fdio.infra.ansible/inventories/cloud_inventory/hosts.yaml" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-aws-c5n/output.tf b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/output.tf diff --git a/fdio.infra.terraform/terraform-aws-3n-aws-c5n/providers.tf b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/providers.tf new file mode 100644 index 0000000000..2482ca2839 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://10.30.51.24:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-aws-c5n/topology-3n-aws-c5n.tftpl b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/topology-3n-aws-c5n.tftpl new file mode 100644 index 0000000000..9886b56a8d --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/topology-3n-aws-c5n.tftpl @@ -0,0 +1,72 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/3_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 3-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 50GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-50G + port2: + # tg_instance/p2 - 50GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-50G + DUT1: + type: DUT + host: ${dut1_public_ip} + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut1_instance/p1 - 50GE port1 on ENA NIC. + mac_address: "${dut1_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-50G + port2: + # dut1_instance/p2 - 50GE port2 on ENA NIC. + mac_address: "${dut1_if2_mac}" + pci_address: "0000:00:07.0" + link: link21 + model: Amazon-Nitro-50G + DUT2: + type: DUT + host: ${dut2_public_ip} + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut2_instance/p1 - 50GE port1 on ENA NIC. + mac_address: "${dut2_if1_mac}" + pci_address: "0000:00:06.0" + link: link21 + model: Amazon-Nitro-50G + port2: + # dut2_instance/p2 - 50GE port1 on ENA NIC. + mac_address: "${dut2_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-50G
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-aws-c5n/variables.tf b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/variables.tf new file mode 100644 index 0000000000..d64dd5b241 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/variables.tf @@ -0,0 +1,216 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-central-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-3n-aws-c5n" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "ED25519" +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07430bfa17fd4e597" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c5n.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut1_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-0a890555652963ec2" +} + +variable "sut1_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut1_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut1_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c5n.4xlarge" +} + +variable "sut1_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.11" +} + +variable "sut1_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut2_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07898402cb1fd6561" +} + +variable "sut2_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut2_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut2_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c5n.4xlarge" +} + +variable "sut2_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.12" +} + +variable "sut2_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.254" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/24" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/24" +} + +variable "sut1_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "sut1_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "200.0.0.101" +} + +variable "sut2_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "200.0.0.102" +} + +variable "sut2_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.11" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-3n-aws-c5n/versions.tf b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/versions.tf new file mode 100644 index 0000000000..589699691e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-aws-c5n/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c6gn/hosts.tftpl b/fdio.infra.terraform/terraform-aws-3n-c6gn/hosts.tftpl new file mode 100644 index 0000000000..e88c8ba510 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6gn/hosts.tftpl @@ -0,0 +1,9 @@ +all: + children: + tg: + hosts: + ${tg_public_ip} + sut: + hosts: + ${dut1_public_ip} + ${dut2_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c6gn/main.tf b/fdio.infra.terraform/terraform-aws-3n-c6gn/main.tf new file mode 100644 index 0000000000..dc0ad6a210 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6gn/main.tf @@ -0,0 +1,457 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "eu-central-1a" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "3n-c6gn" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" + sut2_name = "${var.resource_prefix}-${var.testbed_name}-sut2" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_c" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "200.0.0.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 3) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_d" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.20.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 4) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ip = var.tg_if1_private_ip + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_d, + aws_instance.tg + ] + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_instance" "sut1" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut1_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut1_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut1_instance_initiated_shutdown_behavior + instance_type = var.sut1_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut1_private_ip + source_dest_check = var.sut1_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if1" { + depends_on = [ + module.subnet_b, + aws_instance.sut1 + ] + private_ips = [var.sut1_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 1 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if2" { + depends_on = [ + module.subnet_c, + aws_instance.sut1 + ] + private_ips = [var.sut1_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_c.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 2 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut1_if1" { + id = aws_network_interface.sut1_if1.id +} + +data "aws_network_interface" "sut1_if2" { + id = aws_network_interface.sut1_if2.id +} + +resource "aws_instance" "sut2" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut2_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut2_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut2_instance_initiated_shutdown_behavior + instance_type = var.sut2_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut2_private_ip + source_dest_check = var.sut2_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut2_if1" { + depends_on = [ + module.subnet_c, + aws_instance.sut2 + ] + private_ips = [var.sut2_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut2_source_dest_check + subnet_id = module.subnet_c.subnet_id + + attachment { + instance = aws_instance.sut2.id + device_index = 1 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut2_if2" { + depends_on = [ + module.subnet_d, + aws_instance.sut2 + ] + private_ips = [var.sut2_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut2_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.sut2.id + device_index = 2 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut2_if1" { + id = aws_network_interface.sut2_if1.id +} + +data "aws_network_interface" "sut2_if2" { + id = aws_network_interface.sut2_if2.id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut1" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut1.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut2" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut2.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "local_file" "topology_file" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1, + aws_instance.sut2 + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + dut1_if1_mac = data.aws_network_interface.sut1_if1.mac_address + dut1_if2_mac = data.aws_network_interface.sut1_if2.mac_address + dut2_if1_mac = data.aws_network_interface.sut2_if1.mac_address + dut2_if2_mac = data.aws_network_interface.sut2_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + dut2_public_ip = aws_instance.sut2.public_ip + } + ) + filename = "${path.module}/../../topologies/available/${local.topology_name}-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1, + aws_instance.sut2 + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + dut2_public_ip = aws_instance.sut2.public_ip + } + ) + filename = "${path.module}/../../fdio.infra.ansible/inventories/cloud_inventory/hosts.yaml" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c6gn/output.tf b/fdio.infra.terraform/terraform-aws-3n-c6gn/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6gn/output.tf diff --git a/fdio.infra.terraform/terraform-aws-3n-c6gn/providers.tf b/fdio.infra.terraform/terraform-aws-3n-c6gn/providers.tf new file mode 100644 index 0000000000..2482ca2839 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6gn/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://10.30.51.24:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c6gn/topology-3n-c6gn.tftpl b/fdio.infra.terraform/terraform-aws-3n-c6gn/topology-3n-c6gn.tftpl new file mode 100644 index 0000000000..dc6d869a02 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6gn/topology-3n-c6gn.tftpl @@ -0,0 +1,73 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/3_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 3-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-100G + port2: + # tg_instance/p2 - 100GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-100G + DUT1: + type: DUT + host: "${dut1_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut1_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${dut1_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-100G + port2: + # dut1_instance/p2 - 100GE port2 on ENA NIC. + mac_address: "${dut1_if2_mac}" + pci_address: "0000:00:07.0" + link: link21 + model: Amazon-Nitro-100G + DUT2: + type: DUT + host: "${dut2_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut2_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${dut2_if1_mac}" + pci_address: "0000:00:06.0" + link: link21 + model: Amazon-Nitro-100G + port2: + # dut2_instance/p2 - 100GE port1 on ENA NIC. + mac_address: "${dut2_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-100G + diff --git a/fdio.infra.terraform/terraform-aws-3n-c6gn/variables.tf b/fdio.infra.terraform/terraform-aws-3n-c6gn/variables.tf new file mode 100644 index 0000000000..23ae7cf42a --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6gn/variables.tf @@ -0,0 +1,216 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-central-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-3n-c6gn" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "ED25519" +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07430bfa17fd4e597" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut1_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-0cebabdc14ee56909" +} + +variable "sut1_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut1_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut1_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6gn.4xlarge" +} + +variable "sut1_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.11" +} + +variable "sut1_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut2_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-0cebabdc14ee56909" +} + +variable "sut2_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut2_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut2_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6gn.4xlarge" +} + +variable "sut2_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.12" +} + +variable "sut2_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.254" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/24" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/24" +} + +variable "sut1_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "sut1_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "200.0.0.101" +} + +variable "sut2_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "200.0.0.102" +} + +variable "sut2_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.11" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-3n-c6gn/versions.tf b/fdio.infra.terraform/terraform-aws-3n-c6gn/versions.tf new file mode 100644 index 0000000000..589699691e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6gn/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c6in/hosts.tftpl b/fdio.infra.terraform/terraform-aws-3n-c6in/hosts.tftpl new file mode 100644 index 0000000000..e88c8ba510 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6in/hosts.tftpl @@ -0,0 +1,9 @@ +all: + children: + tg: + hosts: + ${tg_public_ip} + sut: + hosts: + ${dut1_public_ip} + ${dut2_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c6in/main.tf b/fdio.infra.terraform/terraform-aws-3n-c6in/main.tf new file mode 100644 index 0000000000..f1bb1b0f03 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6in/main.tf @@ -0,0 +1,457 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "eu-central-1b" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "3n-c6in" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" + sut2_name = "${var.resource_prefix}-${var.testbed_name}-sut2" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_c" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "200.0.0.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 3) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_d" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.20.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 4) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ip = var.tg_if1_private_ip + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_d, + aws_instance.tg + ] + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_instance" "sut1" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut1_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut1_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut1_instance_initiated_shutdown_behavior + instance_type = var.sut1_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut1_private_ip + source_dest_check = var.sut1_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if1" { + depends_on = [ + module.subnet_b, + aws_instance.sut1 + ] + private_ips = [var.sut1_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 1 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if2" { + depends_on = [ + module.subnet_c, + aws_instance.sut1 + ] + private_ips = [var.sut1_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_c.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 2 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut1_if1" { + id = aws_network_interface.sut1_if1.id +} + +data "aws_network_interface" "sut1_if2" { + id = aws_network_interface.sut1_if2.id +} + +resource "aws_instance" "sut2" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut2_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut2_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut2_instance_initiated_shutdown_behavior + instance_type = var.sut2_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut2_private_ip + source_dest_check = var.sut2_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut2_if1" { + depends_on = [ + module.subnet_c, + aws_instance.sut2 + ] + private_ips = [var.sut2_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut2_source_dest_check + subnet_id = module.subnet_c.subnet_id + + attachment { + instance = aws_instance.sut2.id + device_index = 1 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut2_if2" { + depends_on = [ + module.subnet_d, + aws_instance.sut2 + ] + private_ips = [var.sut2_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut2_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.sut2.id + device_index = 2 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut2_if1" { + id = aws_network_interface.sut2_if1.id +} + +data "aws_network_interface" "sut2_if2" { + id = aws_network_interface.sut2_if2.id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut1" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut1.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut2" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut2.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "local_file" "topology_file" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1, + aws_instance.sut2 + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + dut1_if1_mac = data.aws_network_interface.sut1_if1.mac_address + dut1_if2_mac = data.aws_network_interface.sut1_if2.mac_address + dut2_if1_mac = data.aws_network_interface.sut2_if1.mac_address + dut2_if2_mac = data.aws_network_interface.sut2_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + dut2_public_ip = aws_instance.sut2.public_ip + } + ) + filename = "${path.module}/../../topologies/available/${local.topology_name}-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1, + aws_instance.sut2 + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + dut2_public_ip = aws_instance.sut2.public_ip + } + ) + filename = "${path.module}/../../fdio.infra.ansible/inventories/cloud_inventory/hosts.yaml" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c6in/output.tf b/fdio.infra.terraform/terraform-aws-3n-c6in/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6in/output.tf diff --git a/fdio.infra.terraform/terraform-aws-3n-c6in/providers.tf b/fdio.infra.terraform/terraform-aws-3n-c6in/providers.tf new file mode 100644 index 0000000000..2482ca2839 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6in/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://10.30.51.24:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c6in/topology-3n-c6in.tftpl b/fdio.infra.terraform/terraform-aws-3n-c6in/topology-3n-c6in.tftpl new file mode 100644 index 0000000000..2ec39d0ea9 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6in/topology-3n-c6in.tftpl @@ -0,0 +1,73 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/3_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 3-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 200GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-200G + port2: + # tg_instance/p2 - 200GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-200G + DUT1: + type: DUT + host: "${dut1_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut1_instance/p1 - 200GE port1 on ENA NIC. + mac_address: "${dut1_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-200G + port2: + # dut1_instance/p2 - 200GE port2 on ENA NIC. + mac_address: "${dut1_if2_mac}" + pci_address: "0000:00:07.0" + link: link21 + model: Amazon-Nitro-200G + DUT2: + type: DUT + host: "${dut2_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut2_instance/p1 - 200GE port1 on ENA NIC. + mac_address: "${dut2_if1_mac}" + pci_address: "0000:00:06.0" + link: link21 + model: Amazon-Nitro-200G + port2: + # dut2_instance/p2 - 200GE port1 on ENA NIC. + mac_address: "${dut2_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-200G + diff --git a/fdio.infra.terraform/terraform-aws-3n-c6in/variables.tf b/fdio.infra.terraform/terraform-aws-3n-c6in/variables.tf new file mode 100644 index 0000000000..3255cab3f3 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6in/variables.tf @@ -0,0 +1,216 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-central-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-3n-c6in" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "ED25519" +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07430bfa17fd4e597" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut1_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-0a890555652963ec2" +} + +variable "sut1_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut1_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut1_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "sut1_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.11" +} + +variable "sut1_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut2_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-07898402cb1fd6561" +} + +variable "sut2_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut2_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut2_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "sut2_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.12" +} + +variable "sut2_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.254" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/24" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/24" +} + +variable "sut1_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "sut1_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "200.0.0.101" +} + +variable "sut2_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "200.0.0.102" +} + +variable "sut2_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.11" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-3n-c6in/versions.tf b/fdio.infra.terraform/terraform-aws-3n-c6in/versions.tf new file mode 100644 index 0000000000..589699691e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c6in/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c7gn/hosts.tftpl b/fdio.infra.terraform/terraform-aws-3n-c7gn/hosts.tftpl new file mode 100644 index 0000000000..e88c8ba510 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c7gn/hosts.tftpl @@ -0,0 +1,9 @@ +all: + children: + tg: + hosts: + ${tg_public_ip} + sut: + hosts: + ${dut1_public_ip} + ${dut2_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c7gn/main.tf b/fdio.infra.terraform/terraform-aws-3n-c7gn/main.tf new file mode 100644 index 0000000000..68d2dd9be2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c7gn/main.tf @@ -0,0 +1,457 @@ +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault-name}-path" + role = "${var.vault-name}-role" +} + +locals { + ansible_python_executable = "/usr/bin/python3" + availability_zone = "${var.region}a" + name = "csit-vpc" + environment = "csit-vpc-environment" + key_pair_key_name = "${var.resource_prefix}-${var.testbed_name}-pk" + placement_group_name = "${var.resource_prefix}-${var.testbed_name}-pg" + security_group_name = "${var.resource_prefix}-${var.testbed_name}-sg" + testbed_name = "testbed1" + topology_name = "3n-c7gn" + tg_name = "${var.resource_prefix}-${var.testbed_name}-tg" + sut1_name = "${var.resource_prefix}-${var.testbed_name}-sut1" + sut2_name = "${var.resource_prefix}-${var.testbed_name}-sut2" +} + +# Create VPC +module "vpc" { + source = "../terraform-aws-vpc" + security_group_name = local.security_group_name + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment +} + +# Create Subnet +module "subnet_b" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 2) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_c" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "200.0.0.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 3) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +module "subnet_d" { + source = "../terraform-aws-subnet" + subnet_cidr_block = "192.168.20.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 4) + subnet_availability_zone = local.availability_zone + tags_name = local.name + tags_environment = local.environment + subnet_vpc_id = module.vpc.vpc_id +} + +# Create Private Key +module "private_key" { + source = "pmikus/private-key/tls" + version = "4.0.4" + + private_key_algorithm = var.private_key_algorithm +} + +# Create Key Pair +module "key_pair" { + source = "pmikus/key-pair/aws" + version = "5.7.0" + + key_pair_key_name = local.key_pair_key_name + key_pair_public_key = module.private_key.public_key_openssh + + key_pair_tags = { + "Environment" = local.environment + } +} + +# Create Placement Group +resource "aws_placement_group" "placement_group" { + name = local.placement_group_name + strategy = var.placement_group_strategy +} + +# Create Instance +resource "aws_instance" "tg" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.tg_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.tg_associate_public_ip_address + instance_initiated_shutdown_behavior = var.tg_instance_initiated_shutdown_behavior + instance_type = var.tg_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.tg_private_ip + source_dest_check = var.tg_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "1" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if1" { + depends_on = [ + module.subnet_b, + aws_instance.tg + ] + private_ip = var.tg_if1_private_ip + private_ips = [var.tg_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 1 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "tg_if2" { + depends_on = [ + module.subnet_d, + aws_instance.tg + ] + private_ips = [var.tg_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.tg_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.tg.id + device_index = 2 + } + + tags = { + "Name" = local.tg_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "tg_if1" { + id = aws_network_interface.tg_if1.id +} + +data "aws_network_interface" "tg_if2" { + id = aws_network_interface.tg_if2.id +} + +resource "aws_route" "route_tg_if1" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if1 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_route" "route_tg_if2" { + depends_on = [ + aws_instance.tg + ] + destination_cidr_block = var.destination_cidr_block_tg_if2 + network_interface_id = aws_instance.tg.primary_network_interface_id + route_table_id = module.vpc.vpc_main_route_table_id +} + +resource "aws_instance" "sut1" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut1_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut1_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut1_instance_initiated_shutdown_behavior + instance_type = var.sut1_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut1_private_ip + source_dest_check = var.sut1_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if1" { + depends_on = [ + module.subnet_b, + aws_instance.sut1 + ] + private_ips = [var.sut1_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_b.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 1 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut1_if2" { + depends_on = [ + module.subnet_c, + aws_instance.sut1 + ] + private_ips = [var.sut1_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut1_source_dest_check + subnet_id = module.subnet_c.subnet_id + + attachment { + instance = aws_instance.sut1.id + device_index = 2 + } + + tags = { + "Name" = local.sut1_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut1_if1" { + id = aws_network_interface.sut1_if1.id +} + +data "aws_network_interface" "sut1_if2" { + id = aws_network_interface.sut1_if2.id +} + +resource "aws_instance" "sut2" { + depends_on = [ + module.vpc, + aws_placement_group.placement_group + ] + ami = var.sut2_ami + availability_zone = local.availability_zone + associate_public_ip_address = var.sut2_associate_public_ip_address + instance_initiated_shutdown_behavior = var.sut2_instance_initiated_shutdown_behavior + instance_type = var.sut2_instance_type + key_name = module.key_pair.key_pair_key_name + placement_group = aws_placement_group.placement_group.id + private_ip = var.sut2_private_ip + source_dest_check = var.sut2_source_dest_check + subnet_id = module.vpc.vpc_subnet_id + vpc_security_group_ids = [module.vpc.vpc_security_group_id] + # host_id = "2" + + root_block_device { + delete_on_termination = true + volume_size = 50 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut2_if1" { + depends_on = [ + module.subnet_c, + aws_instance.sut2 + ] + private_ips = [var.sut2_if1_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut2_source_dest_check + subnet_id = module.subnet_c.subnet_id + + attachment { + instance = aws_instance.sut2.id + device_index = 1 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +resource "aws_network_interface" "sut2_if2" { + depends_on = [ + module.subnet_d, + aws_instance.sut2 + ] + private_ips = [var.sut2_if2_private_ip] + security_groups = [module.vpc.vpc_security_group_id] + source_dest_check = var.sut2_source_dest_check + subnet_id = module.subnet_d.subnet_id + + attachment { + instance = aws_instance.sut2.id + device_index = 2 + } + + tags = { + "Name" = local.sut2_name + "Environment" = local.environment + } +} + +data "aws_network_interface" "sut2_if1" { + id = aws_network_interface.sut2_if1.id +} + +data "aws_network_interface" "sut2_if2" { + id = aws_network_interface.sut2_if2.id +} + +resource "null_resource" "deploy_tg" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.tg.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut1" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut1.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "null_resource" "deploy_sut2" { + depends_on = [ + aws_instance.tg, + aws_network_interface.tg_if1, + aws_network_interface.tg_if2, + aws_instance.sut1, + aws_network_interface.sut1_if1, + aws_network_interface.sut1_if2, + aws_instance.sut2, + aws_network_interface.sut2_if1, + aws_network_interface.sut2_if2 + ] + + connection { + user = "ubuntu" + host = aws_instance.sut2.public_ip + private_key = module.private_key.private_key_pem + } + + provisioner "remote-exec" { + inline = var.first_run_commands + } +} + +resource "local_file" "topology_file" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1, + aws_instance.sut2 + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = data.aws_network_interface.tg_if1.mac_address + tg_if2_mac = data.aws_network_interface.tg_if2.mac_address + dut1_if1_mac = data.aws_network_interface.sut1_if1.mac_address + dut1_if2_mac = data.aws_network_interface.sut1_if2.mac_address + dut2_if1_mac = data.aws_network_interface.sut2_if1.mac_address + dut2_if2_mac = data.aws_network_interface.sut2_if2.mac_address + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + dut2_public_ip = aws_instance.sut2.public_ip + } + ) + filename = "${path.module}/../../topologies/available/${local.topology_name}-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + aws_instance.tg, + aws_instance.sut1, + aws_instance.sut2 + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = aws_instance.tg.public_ip + dut1_public_ip = aws_instance.sut1.public_ip + dut2_public_ip = aws_instance.sut2.public_ip + } + ) + filename = "${path.module}/../../fdio.infra.ansible/inventories/cloud_inventory/hosts.yaml" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c7gn/output.tf b/fdio.infra.terraform/terraform-aws-3n-c7gn/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c7gn/output.tf diff --git a/fdio.infra.terraform/terraform-aws-3n-c7gn/providers.tf b/fdio.infra.terraform/terraform-aws-3n-c7gn/providers.tf new file mode 100644 index 0000000000..2482ca2839 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c7gn/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = "http://10.30.51.24:8200" + skip_tls_verify = true + token = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c7gn/topology-3n-c7gn.tftpl b/fdio.infra.terraform/terraform-aws-3n-c7gn/topology-3n-c7gn.tftpl new file mode 100644 index 0000000000..65106da556 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c7gn/topology-3n-c7gn.tftpl @@ -0,0 +1,72 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/3_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 3-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-100G + port2: + # tg_instance/p2 - 100GE port2 on ENA NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-100G + DUT1: + type: DUT + host: "${dut1_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut1_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${dut1_if1_mac}" + pci_address: "0000:00:06.0" + link: link1 + model: Amazon-Nitro-100G + port2: + # dut1_instance/p2 - 100GE port2 on ENA NIC. + mac_address: "${dut1_if2_mac}" + pci_address: "0000:00:07.0" + link: link21 + model: Amazon-Nitro-100G + DUT2: + type: DUT + host: "${dut2_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut2_instance/p1 - 100GE port1 on ENA NIC. + mac_address: "${dut2_if1_mac}" + pci_address: "0000:00:06.0" + link: link21 + model: Amazon-Nitro-100G + port2: + # dut2_instance/p2 - 100GE port1 on ENA NIC. + mac_address: "${dut2_if2_mac}" + pci_address: "0000:00:07.0" + link: link2 + model: Amazon-Nitro-100G
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-3n-c7gn/variables.tf b/fdio.infra.terraform/terraform-aws-3n-c7gn/variables.tf new file mode 100644 index 0000000000..3ad51afeba --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c7gn/variables.tf @@ -0,0 +1,216 @@ +variable "vault-name" { + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "region" { + description = "AWS Region." + type = string + default = "eu-west-1" +} + +variable "resource_prefix" { + description = "Resources name prefix." + type = string + default = "csit-3n-c7gn" +} + +variable "testbed_name" { + description = "Testbed name." + type = string + default = "testbed1" +} + +# Variables for Private Key +variable "private_key_algorithm" { + description = "The name of the algorithm to use for the key." + type = string + default = "ED25519" +} + +# Variables for Placement Group +variable "placement_group_strategy" { + description = "The placement strategy. Can be cluster, partition or spread." + type = string + default = "cluster" +} + +# Variables for Instance +variable "tg_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-0b5aa26a6e4192705" +} + +variable "tg_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "tg_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "tg_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c6in.4xlarge" +} + +variable "tg_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.10" +} + +variable "tg_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut1_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-08930f71bd0be1085" +} + +variable "sut1_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut1_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut1_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c7gn.4xlarge" +} + +variable "sut1_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.11" +} + +variable "sut1_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +variable "sut2_ami" { + description = "AMI to use for the instance." + type = string + default = "ami-08930f71bd0be1085" +} + +variable "sut2_associate_public_ip_address" { + description = "Whether to associate a public IP address with an instance in a VPC." + type = bool + default = true +} + +variable "sut2_instance_initiated_shutdown_behavior" { + description = "Shutdown behavior for the instance." + type = string + default = "terminate" +} + +variable "sut2_instance_type" { + description = "The instance type to use for the instance." + type = string + default = "c7gn.4xlarge" +} + +variable "sut2_private_ip" { + description = "Private IP address to associate with the instance in a VPC." + type = string + default = "192.168.0.12" +} + +variable "sut2_source_dest_check" { + description = "Controls if traffic is routed to the instance when the destination address does not match the instance." + type = bool + default = false +} + +# Variables for Network Interface +variable "tg_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.254" +} + +variable "tg_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.254" +} + +variable "destination_cidr_block_tg_if1" { + description = "The destination CIDR block." + type = string + default = "10.0.0.0/24" +} + +variable "destination_cidr_block_tg_if2" { + description = "The destination CIDR block." + type = string + default = "20.0.0.0/24" +} + +variable "sut1_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.10.11" +} + +variable "sut1_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "200.0.0.101" +} + +variable "sut2_if1_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "200.0.0.102" +} + +variable "sut2_if2_private_ip" { + description = "List of private IPs to assign to the ENI without regard to order." + type = string + default = "192.168.20.11" +} + +# Variables for Null Resource +variable "first_run_commands" { + description = "List of private IPs to assign to the ENI without regard to order." + type = list(string) + default = [ + "sudo sed -i 's/^PasswordAuthentication/#PasswordAuthentication/' /etc/ssh/sshd_config", + "sudo systemctl restart sshd", + "sudo useradd --create-home -s /bin/bash provisionuser", + "echo 'provisionuser:Csit1234' | sudo chpasswd", + "echo 'provisionuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers", + "sudo useradd --create-home -s /bin/bash testuser", + "echo 'testuser:Csit1234' | sudo chpasswd", + "echo 'testuser ALL = (ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers" + ] +} + +# Variables for Null Resource +variable "ansible_topology_path" { + description = "Ansible topology path." + type = string + default = "../../fdio.infra.ansible/cloud_topology.yaml" +} diff --git a/fdio.infra.terraform/terraform-aws-3n-c7gn/versions.tf b/fdio.infra.terraform/terraform-aws-3n-c7gn/versions.tf new file mode 100644 index 0000000000..589699691e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-3n-c7gn/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + vault = { + version = ">= 3.15.2" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/README.md b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/README.md new file mode 100644 index 0000000000..0ab18bdbb8 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/README.md @@ -0,0 +1,38 @@ +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.4 | +| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 4.3.0 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 4.3.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_elastic_beanstalk_application_version.application_version](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elastic_beanstalk_application_version) | resource | +| [aws_s3_bucket.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_object.object](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_application_description"></a> [application\_description](#input\_application\_description) | Short description of the Application Version. | `string` | `"Beanstalk Application"` | no | +| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | Name of the Beanstalk Application the version is associated. | `string` | `"Beanstalk"` | no | +| <a name="input_application_version_name"></a> [application\_version\_name](#input\_application\_version\_name) | Unique name for the this Application Version. | `string` | `"Beanstalk Version"` | no | + +## Outputs + +No outputs. +<!-- END_TF_DOCS -->
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/main.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/main.tf new file mode 100644 index 0000000000..652509225f --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/main.tf @@ -0,0 +1,4 @@ +module "elastic_beanstalk_application_version" { + source = "../" + application_description = var.application_description +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/output.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/output.tf diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/providers.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/providers.tf new file mode 100644 index 0000000000..5ff54f0d65 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = var.region +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/variables.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/variables.tf new file mode 100644 index 0000000000..12af1d64c6 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/variables.tf @@ -0,0 +1,11 @@ +variable "region" { + description = "AWS Region." + type = string + default = "us-east-1" +} + +variable "application_description" { + description = "Short description of the application." + type = string + default = "Beanstalk Application" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/versions.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/versions.tf new file mode 100644 index 0000000000..af1be4a4e1 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/example/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.3.0" + } + } + required_version = ">= 1.1.4" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/main.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/main.tf new file mode 100644 index 0000000000..ace3aebbbc --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/main.tf @@ -0,0 +1,28 @@ +locals { + key = "${var.application_name_version}-${uuid()}.zip" + tags = { + "Name" = "${var.application_name}" + "Environment" = "${var.application_name}" + } +} + +# Create elastic beanstalk Application Version +# resource "aws_s3_bucket" "bucket" { +# bucket = var.application_bucket +# tags = local.tags +# } +resource "aws_s3_object" "object" { + bucket = var.application_bucket + key = local.key + source = var.application_source + tags = local.tags +} + +resource "aws_elastic_beanstalk_application_version" "application_version" { + application = var.application_name + description = var.application_description + bucket = var.application_bucket + key = aws_s3_object.object.id + name = var.application_name_version + tags = local.tags +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/output.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/output.tf new file mode 100644 index 0000000000..4262bbe6cf --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/output.tf @@ -0,0 +1,3 @@ +output "application_version" { + value = aws_elastic_beanstalk_application_version.application_version.name +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/variables.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/variables.tf new file mode 100644 index 0000000000..8d7dd45755 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/variables.tf @@ -0,0 +1,29 @@ +variable "application_bucket" { + description = "The name of the bucket." + type = string + default = "elasticbeanstalk-eu-central-1" +} + +variable "application_description" { + description = "Short description of the Application Version." + type = string + default = "Beanstalk Application" +} + +variable "application_name" { + description = "Name of the Beanstalk Application." + type = string + default = "beanstalk" +} + +variable "application_name_version" { + description = "Version of the Beanstalk Application." + type = string + default = "beanstalk-1" +} + +variable "application_source" { + description = "The source file with application code." + type = string + default = "app.zip" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/versions.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/versions.tf new file mode 100644 index 0000000000..1c82745471 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application-version/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + } + required_version = ">= 1.4.2" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/README.md b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/README.md new file mode 100644 index 0000000000..d149d90038 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/README.md @@ -0,0 +1,41 @@ +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.4 | +| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 4.3.0 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 4.3.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_elastic_beanstalk_application.application](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elastic_beanstalk_application) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_application_description"></a> [application\_description](#input\_application\_description) | Short description of the application. | `string` | `"Beanstalk Application"` | no | +| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | The name of the application, must be unique within account. | `string` | `"Beanstalk"` | no | +| <a name="input_appversion_lifecycle_delete_source_from_s3"></a> [appversion\_lifecycle\_delete\_source\_from\_s3](#input\_appversion\_lifecycle\_delete\_source\_from\_s3) | Whether to delete application versions from S3 source. | `bool` | `false` | no | +| <a name="input_appversion_lifecycle_max_count"></a> [appversion\_lifecycle\_max\_count](#input\_appversion\_lifecycle\_max\_count) | The max number of application versions to keep. | `number` | `2` | no | +| <a name="input_appversion_lifecycle_service_role_arn"></a> [appversion\_lifecycle\_service\_role\_arn](#input\_appversion\_lifecycle\_service\_role\_arn) | The service role ARN to use for application version cleanup. If left empty, the `appversion_lifecycle` block will not be created. | `string` | `""` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| <a name="output_application_description"></a> [application\_description](#output\_application\_description) | n/a | +| <a name="output_application_name"></a> [application\_name](#output\_application\_name) | n/a | +<!-- END_TF_DOCS -->
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/main.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/main.tf new file mode 100644 index 0000000000..410d1abc59 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/main.tf @@ -0,0 +1,4 @@ +module "elastic_beanstalk_application" { + source = "../" + application_description = var.application_description +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/output.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/output.tf new file mode 100644 index 0000000000..290e2a1c5a --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/output.tf @@ -0,0 +1,9 @@ +output "elastic_beanstalk_application_name" { + value = module.elastic_beanstalk_application.application_name + description = "Elastic Beanstalk Application name" +} + +output "elastic_beanstalk_application_description" { + value = module.elastic_beanstalk_application.application_description + description = "Elastic Beanstalk Application description" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/providers.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/providers.tf new file mode 100644 index 0000000000..5ff54f0d65 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = var.region +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/variables.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/variables.tf new file mode 100644 index 0000000000..12af1d64c6 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/variables.tf @@ -0,0 +1,11 @@ +variable "region" { + description = "AWS Region." + type = string + default = "us-east-1" +} + +variable "application_description" { + description = "Short description of the application." + type = string + default = "Beanstalk Application" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/versions.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/versions.tf new file mode 100644 index 0000000000..af1be4a4e1 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/example/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.3.0" + } + } + required_version = ">= 1.1.4" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/main.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/main.tf new file mode 100644 index 0000000000..909d6fca4d --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/main.tf @@ -0,0 +1,21 @@ +locals { + tags = { + "Name" = "${var.application_name}" + "Environment" = "${var.application_name}" + } +} + +resource "aws_elastic_beanstalk_application" "application" { + name = var.application_name + description = var.application_description + tags = local.tags + + dynamic "appversion_lifecycle" { + for_each = var.appversion_lifecycle_service_role_arn != "" ? ["true"] : [] + content { + service_role = var.appversion_lifecycle_service_role_arn + max_count = var.appversion_lifecycle_max_count + delete_source_from_s3 = var.appversion_lifecycle_delete_source_from_s3 + } + } +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/output.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/output.tf new file mode 100644 index 0000000000..ce7f978e53 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/output.tf @@ -0,0 +1,7 @@ +output "application_name" { + value = aws_elastic_beanstalk_application.application.name +} + +output "application_description" { + value = aws_elastic_beanstalk_application.application.description +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/variables.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/variables.tf new file mode 100644 index 0000000000..38090c99b5 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/variables.tf @@ -0,0 +1,29 @@ +variable "application_description" { + description = "Short description of the application." + type = string + default = "Beanstalk Application" +} + +variable "application_name" { + description = "The name of the application, must be unique within account." + type = string + default = "Beanstalk" +} + +variable "appversion_lifecycle_service_role_arn" { + description = "The service role ARN to use for application version cleanup. If left empty, the `appversion_lifecycle` block will not be created." + type = string + default = "" +} + +variable "appversion_lifecycle_max_count" { + description = "The max number of application versions to keep." + type = number + default = 2 +} + +variable "appversion_lifecycle_delete_source_from_s3" { + description = "Whether to delete application versions from S3 source." + type = bool + default = false +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/versions.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/versions.tf new file mode 100644 index 0000000000..8ad3fd72c6 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-application/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + } + required_version = ">= 1.5.4" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/README.md b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/README.md new file mode 100644 index 0000000000..f3bc3e23ec --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/README.md @@ -0,0 +1,106 @@ +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.4 | +| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 4.3.0 | +| <a name="requirement_vault"></a> [vault](#requirement\_vault) | >= 3.2.1 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 4.3.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_elastic_beanstalk_environment.environment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elastic_beanstalk_environment) | resource | +| [aws_iam_instance_profile.ec2_iam_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_role.ec2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role.service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | +| [aws_iam_role_policy_attachment.ecr_readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.enhanced_health](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.multicontainer_docker](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.ssm_automation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.ssm_ec2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.web_tier](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_iam_role_policy_attachment.worker_tier](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | +| [aws_internet_gateway.internet_gateway](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource | +| [aws_route.route](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource | +| [aws_ssm_activation.ec2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_activation) | resource | +| [aws_subnet.subnet](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource | +| [aws_iam_policy_document.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.ec2](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_application_description"></a> [application\_description](#input\_application\_description) | Short description of the application. | `string` | `"Beanstalk Application"` | no | +| <a name="input_application_name"></a> [application\_name](#input\_application\_name) | The name of the application, must be unique within account. | `string` | `"Beanstalk"` | no | +| <a name="input_appversion_lifecycle_delete_source_from_s3"></a> [appversion\_lifecycle\_delete\_source\_from\_s3](#input\_appversion\_lifecycle\_delete\_source\_from\_s3) | Whether to delete application versions from S3 source | `bool` | `false` | no | +| <a name="input_appversion_lifecycle_max_count"></a> [appversion\_lifecycle\_max\_count](#input\_appversion\_lifecycle\_max\_count) | The max number of application versions to keep | `number` | `2` | no | +| <a name="input_appversion_lifecycle_service_role_arn"></a> [appversion\_lifecycle\_service\_role\_arn](#input\_appversion\_lifecycle\_service\_role\_arn) | The service role ARN to use for application version cleanup. If left empty, the `appversion_lifecycle` block will not be created. | `string` | `""` | no | +| <a name="input_associate_public_ip_address"></a> [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Whether to associate public IP addresses to the instances. | `bool` | `true` | no | +| <a name="input_autoscaling_asg_maxsize"></a> [autoscaling\_asg\_maxsize](#input\_autoscaling\_asg\_maxsize) | Maximum instances to launch | `number` | `2` | no | +| <a name="input_autoscaling_asg_minsize"></a> [autoscaling\_asg\_minsize](#input\_autoscaling\_asg\_minsize) | Minumum instances to launch | `number` | `1` | no | +| <a name="input_autoscaling_trigger_lower_breach_scale_increment"></a> [autoscaling\_trigger\_lower\_breach\_scale\_increment](#input\_autoscaling\_trigger\_lower\_breach\_scale\_increment) | How many Amazon EC2 instances to remove when performing a scaling activity. | `number` | `-1` | no | +| <a name="input_autoscaling_trigger_lower_threshold"></a> [autoscaling\_trigger\_lower\_threshold](#input\_autoscaling\_trigger\_lower\_threshold) | Minimum level of autoscale metric to remove an instance | `number` | `20` | no | +| <a name="input_autoscaling_trigger_measure_name"></a> [autoscaling\_trigger\_measure\_name](#input\_autoscaling\_trigger\_measure\_name) | Metric used for your Auto Scaling trigger | `string` | `"CPUUtilization"` | no | +| <a name="input_autoscaling_trigger_statistic"></a> [autoscaling\_trigger\_statistic](#input\_autoscaling\_trigger\_statistic) | Statistic the trigger should use, such as Average | `string` | `"Average"` | no | +| <a name="input_autoscaling_trigger_unit"></a> [autoscaling\_trigger\_unit](#input\_autoscaling\_trigger\_unit) | Unit for the trigger measurement, such as Bytes | `string` | `"Percent"` | no | +| <a name="input_autoscaling_trigger_upper_breach_scale_increment"></a> [autoscaling\_trigger\_upper\_breach\_scale\_increment](#input\_autoscaling\_trigger\_upper\_breach\_scale\_increment) | How many Amazon EC2 instances to add when performing a scaling activity | `number` | `1` | no | +| <a name="input_autoscaling_trigger_upper_threshold"></a> [autoscaling\_trigger\_upper\_threshold](#input\_autoscaling\_trigger\_upper\_threshold) | Maximum level of autoscale metric to add an instance | `number` | `80` | no | +| <a name="input_cloudwatch_logs_delete_on_terminate"></a> [cloudwatch\_logs\_delete\_on\_terminate](#input\_cloudwatch\_logs\_delete\_on\_terminate) | Whether to delete the log groups when the environment is terminated. If false, the logs are kept RetentionInDays days | `bool` | `true` | no | +| <a name="input_cloudwatch_logs_health_delete_on_terminate"></a> [cloudwatch\_logs\_health\_delete\_on\_terminate](#input\_cloudwatch\_logs\_health\_delete\_on\_terminate) | Whether to delete the log group when the environment is terminated. If false, the health data is kept RetentionInDays days. | `bool` | `true` | no | +| <a name="input_cloudwatch_logs_health_health_streaming_enabled"></a> [cloudwatch\_logs\_health\_health\_streaming\_enabled](#input\_cloudwatch\_logs\_health\_health\_streaming\_enabled) | For environments with enhanced health reporting enabled, whether to create a group in CloudWatch Logs for environment health and archive Elastic Beanstalk environment health data. For information about enabling enhanced health, see aws:elasticbeanstalk:healthreporting:system. | `bool` | `true` | no | +| <a name="input_cloudwatch_logs_health_retention_in_days"></a> [cloudwatch\_logs\_health\_retention\_in\_days](#input\_cloudwatch\_logs\_health\_retention\_in\_days) | The number of days to keep the archived health data before it expires. | `number` | `3` | no | +| <a name="input_cloudwatch_logs_retention_in_days"></a> [cloudwatch\_logs\_retention\_in\_days](#input\_cloudwatch\_logs\_retention\_in\_days) | The number of days to keep log events before they expire. | `number` | `3` | no | +| <a name="input_cloudwatch_logs_stream_logs"></a> [cloudwatch\_logs\_stream\_logs](#input\_cloudwatch\_logs\_stream\_logs) | Whether to create groups in CloudWatch Logs for proxy and deployment logs, and stream logs from each instance in your environment | `bool` | `true` | no | +| <a name="input_default_listener_enabled"></a> [default\_listener\_enabled](#input\_default\_listener\_enabled) | Set to false to disable the listener. You can use this option to disable the default listener on port 80. | `bool` | `true` | no | +| <a name="input_elb_scheme"></a> [elb\_scheme](#input\_elb\_scheme) | Specify `internal` if you want to create an internal load balancer in your Amazon VPC so that your Elastic Beanstalk application cannot be accessed from outside your Amazon VPC. | `string` | `"public"` | no | +| <a name="input_environment_application"></a> [environment\_application](#input\_environment\_application) | The name of the application, must be unique within account. | `string` | `"Beanstalk Application"` | no | +| <a name="input_environment_description"></a> [environment\_description](#input\_environment\_description) | Short description of the environment. | `string` | `"Beanstalk Environment"` | no | +| <a name="input_environment_loadbalancer_type"></a> [environment\_loadbalancer\_type](#input\_environment\_loadbalancer\_type) | Load Balancer type, e.g. 'application' or 'classic'. | `string` | `"network"` | no | +| <a name="input_environment_name"></a> [environment\_name](#input\_environment\_name) | A unique name for this Environment. This name is used in the application URL. | `string` | `"Beanstalk-env"` | no | +| <a name="input_environment_process_default_healthcheck_interval"></a> [environment\_process\_default\_healthcheck\_interval](#input\_environment\_process\_default\_healthcheck\_interval) | The interval of time, in seconds, that Elastic Load Balancing checks the health of the Amazon EC2 instances of your application. | `number` | `10` | no | +| <a name="input_environment_process_default_healthy_threshold_count"></a> [environment\_process\_default\_healthy\_threshold\_count](#input\_environment\_process\_default\_healthy\_threshold\_count) | The number of consecutive successful requests before Elastic Load Balancing changes the instance health status. | `number` | `3` | no | +| <a name="input_environment_process_default_port"></a> [environment\_process\_default\_port](#input\_environment\_process\_default\_port) | Port application is listening on. | `number` | `5000` | no | +| <a name="input_environment_process_default_unhealthy_threshold_count"></a> [environment\_process\_default\_unhealthy\_threshold\_count](#input\_environment\_process\_default\_unhealthy\_threshold\_count) | The number of consecutive unsuccessful requests before Elastic Load Balancing changes the instance health status. | `number` | `3` | no | +| <a name="input_environment_solution_stack_name"></a> [environment\_solution\_stack\_name](#input\_environment\_solution\_stack\_name) | A solution stack to base your environment off of. | `string` | `"64bit Amazon Linux 2 v3.3.11 running Python 3.8"` | no | +| <a name="input_environment_tier"></a> [environment\_tier](#input\_environment\_tier) | The environment tier specified. | `string` | `"WebServer"` | no | +| <a name="input_environment_type"></a> [environment\_type](#input\_environment\_type) | Environment type, e.g. 'LoadBalanced' or 'SingleInstance'. If setting to 'SingleInstance', `rolling_update_type` must be set to 'Time', `updating_min_in_service` must be set to 0, and `loadbalancer_subnets` will be unused (it applies to the ELB, which does not exist in SingleInstance environments). | `string` | `"LoadBalanced"` | no | +| <a name="input_environment_variables"></a> [environment\_variables](#input\_environment\_variables) | Map of custom ENV variables to be provided to the application. | `map(string)` | `{}` | no | +| <a name="input_environment_version_label"></a> [environment\_version\_label](#input\_environment\_version\_label) | The name of the Elastic Beanstalk Application Version to use in deployment. | `string` | `""` | no | +| <a name="input_environment_wait_for_ready_timeout"></a> [environment\_wait\_for\_ready\_timeout](#input\_environment\_wait\_for\_ready\_timeout) | The maximum duration to wait for the Elastic Beanstalk Environment to be in a ready state before timing out | `string` | `"20m"` | no | +| <a name="input_healthreporting_system_type"></a> [healthreporting\_system\_type](#input\_healthreporting\_system\_type) | Whether to enable enhanced health reporting for this environment | `string` | `"enhanced"` | no | +| <a name="input_hostmanager_log_publication_control"></a> [hostmanager\_log\_publication\_control](#input\_hostmanager\_log\_publication\_control) | Copy the log files for your application's Amazon EC2 instances to the Amazon S3 bucket associated with your application | `bool` | `true` | no | +| <a name="input_instances_instance_types"></a> [instances\_instance\_types](#input\_instances\_instance\_types) | Instances type | `string` | `"t3.medium"` | no | +| <a name="input_managedactions_managed_actions_enabled"></a> [managedactions\_managed\_actions\_enabled](#input\_managedactions\_managed\_actions\_enabled) | Enable managed platform updates. When you set this to true, you must also specify a `PreferredStartTime` and `UpdateLevel` | `bool` | `true` | no | +| <a name="input_managedactions_platformupdate_instance_refresh_enabled"></a> [managedactions\_platformupdate\_instance\_refresh\_enabled](#input\_managedactions\_platformupdate\_instance\_refresh\_enabled) | Enable weekly instance replacement. | `bool` | `true` | no | +| <a name="input_managedactions_platformupdate_update_level"></a> [managedactions\_platformupdate\_update\_level](#input\_managedactions\_platformupdate\_update\_level) | The highest level of update to apply with managed platform updates | `string` | `"minor"` | no | +| <a name="input_managedactions_preferred_start_time"></a> [managedactions\_preferred\_start\_time](#input\_managedactions\_preferred\_start\_time) | Configure a maintenance window for managed actions in UTC | `string` | `"Sun:10:00"` | no | +| <a name="input_subnet_availability_zone"></a> [subnet\_availability\_zone](#input\_subnet\_availability\_zone) | AWS availability zone | `string` | `"us-east-1a"` | no | +| <a name="input_vpc_cidr_block"></a> [vpc\_cidr\_block](#input\_vpc\_cidr\_block) | The CIDR block for the association. | `string` | `"192.168.0.0/24"` | no | +| <a name="input_vpc_enable_dns_hostnames"></a> [vpc\_enable\_dns\_hostnames](#input\_vpc\_enable\_dns\_hostnames) | Whether or not the VPC has DNS hostname support. | `bool` | `true` | no | +| <a name="input_vpc_enable_dns_support"></a> [vpc\_enable\_dns\_support](#input\_vpc\_enable\_dns\_support) | Whether or not the VPC has DNS support. | `bool` | `true` | no | +| <a name="input_vpc_instance_tenancy"></a> [vpc\_instance\_tenancy](#input\_vpc\_instance\_tenancy) | The allowed tenancy of instances launched into the selected VPC. | `string` | `"default"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| <a name="output_environment_cname"></a> [environment\_cname](#output\_environment\_cname) | n/a | +| <a name="output_environment_name"></a> [environment\_name](#output\_environment\_name) | n/a | +<!-- END_TF_DOCS -->
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/main.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/main.tf new file mode 100644 index 0000000000..c6fcbf858b --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/main.tf @@ -0,0 +1,12 @@ +module "elastic_beanstalk_application" { + source = "../../terraform-aws-elastic-beanstalk-application" + application_description = "FD.io CSIT Results Dashboard" + application_name = "fdio-csit-dash-app" +} + +module "elastic_beanstalk_environment" { + source = "../" + environment_application = module.elastic_beanstalk_application.application_name + environment_description = module.elastic_beanstalk_application.application_description + environment_name = "fdio-csit-dash-env" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/output.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/output.tf new file mode 100644 index 0000000000..290e2a1c5a --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/output.tf @@ -0,0 +1,9 @@ +output "elastic_beanstalk_application_name" { + value = module.elastic_beanstalk_application.application_name + description = "Elastic Beanstalk Application name" +} + +output "elastic_beanstalk_application_description" { + value = module.elastic_beanstalk_application.application_description + description = "Elastic Beanstalk Application description" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/providers.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/providers.tf new file mode 100644 index 0000000000..5ff54f0d65 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = var.region +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/variables.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/variables.tf new file mode 100644 index 0000000000..3c07178e06 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/variables.tf @@ -0,0 +1,23 @@ +variable "region" { + description = "AWS Region." + type = string + default = "us-east-1" +} + +variable "environment_application" { + description = "The name of the application, must be unique within account." + type = string + default = "Beanstalk Application" +} + +variable "application_description" { + description = "Short description of the application." + type = string + default = "Beanstalk Application" +} + +variable "application_name" { + description = "The name of the application, must be unique within account." + type = string + default = "Beanstalk" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/versions.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/versions.tf new file mode 100644 index 0000000000..af1be4a4e1 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/example/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.3.0" + } + } + required_version = ">= 1.1.4" +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/main.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/main.tf new file mode 100644 index 0000000000..44373ed4de --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/main.tf @@ -0,0 +1,690 @@ +locals { + tags = { + "Name" = "${var.application_name}" + "Environment" = "${var.application_name}" + } + + # Settings for all loadbalancer types + generic_elb_settings = [ + { + namespace = "aws:elasticbeanstalk:environment" + name = "LoadBalancerType" + value = var.environment_loadbalancer_type + } + ] + + elb_settings = [ + { + namespace = "aws:ec2:vpc" + name = "ELBSubnets" + value = join(",", [aws_subnet.subnet_a.id, aws_subnet.subnet_b.id]) + }, + { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "Port" + value = var.environment_process_default_port + }, + { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "Protocol" + value = var.environment_loadbalancer_type == "network" ? "TCP" : "HTTP" + }, + { + namespace = "aws:ec2:vpc" + name = "ELBScheme" + value = var.environment_type == "LoadBalanced" ? var.elb_scheme : "" + }, + { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "HealthCheckInterval" + value = var.environment_process_default_healthcheck_interval + }, + { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "HealthyThresholdCount" + value = var.environment_process_default_healthy_threshold_count + }, + { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "UnhealthyThresholdCount" + value = var.environment_process_default_unhealthy_threshold_count + } + ] + + generic_alb_settings = [ + { + namespace = "aws:elbv2:loadbalancer" + name = "SecurityGroups" + value = join(",", sort(var.environment_loadbalancer_security_groups)) + } + ] + + alb_settings = [ + { + namespace = "aws:elbv2:listener:default" + name = "ListenerEnabled" + value = var.default_listener_enabled || var.environment_loadbalancer_ssl_certificate_id == "" ? "true" : "false" + }, + { + namespace = "aws:elbv2:loadbalancer" + name = "ManagedSecurityGroup" + value = var.environment_loadbalancer_managed_security_group + }, + { + namespace = "aws:elbv2:listener:443" + name = "ListenerEnabled" + value = var.environment_loadbalancer_ssl_certificate_id == "" ? "false" : "true" + }, + { + namespace = "aws:elbv2:listener:443" + name = "Protocol" + value = "HTTPS" + }, + { + namespace = "aws:elbv2:listener:443" + name = "SSLCertificateArns" + value = var.environment_loadbalancer_ssl_certificate_id + }, + { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "HealthCheckPath" + value = var.application_healthcheck_url + }, + { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "MatcherHTTPCode" + value = join(",", sort(var.default_matcher_http_code)) + }, + { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "HealthCheckTimeout" + value = var.default_health_check_timeout + } + ] + + nlb_settings = [ + { + namespace = "aws:elbv2:listener:default" + name = "ListenerEnabled" + value = var.default_listener_enabled + } + ] + + settings_nlb = var.environment_loadbalancer_type == "network" ? concat(local.nlb_settings, local.generic_elb_settings, local.elb_settings) : [] + settings_alb = var.environment_loadbalancer_type == "application" ? concat(local.generic_alb_settings, local.alb_settings, local.generic_elb_settings, local.elb_settings) : [] + + # Full set of LoadBlanacer settings. + elb = var.environment_tier == "WebServer" ? concat(local.settings_nlb, local.settings_alb) : [] +} + +# Create elastic beanstalk VPC +resource "aws_vpc" "vpc" { + assign_generated_ipv6_cidr_block = true + cidr_block = var.vpc_cidr_block + enable_dns_hostnames = var.vpc_enable_dns_hostnames + enable_dns_support = var.vpc_enable_dns_support + instance_tenancy = var.vpc_instance_tenancy + tags = local.tags +} + +# Create elastic beanstalk Subnets +resource "aws_subnet" "subnet_a" { + depends_on = [ + aws_vpc.vpc + ] + availability_zone = var.subnet_a_availability_zone + assign_ipv6_address_on_creation = true + cidr_block = var.subnet_a_cidr_block + ipv6_cidr_block = cidrsubnet(aws_vpc.vpc.ipv6_cidr_block, 8, 1) + map_public_ip_on_launch = true + vpc_id = aws_vpc.vpc.id + tags = local.tags +} + +resource "aws_subnet" "subnet_b" { + depends_on = [ + aws_vpc.vpc + ] + availability_zone = var.subnet_b_availability_zone + assign_ipv6_address_on_creation = true + cidr_block = var.subnet_b_cidr_block + ipv6_cidr_block = cidrsubnet(aws_vpc.vpc.ipv6_cidr_block, 8, 2) + map_public_ip_on_launch = true + vpc_id = aws_vpc.vpc.id + tags = local.tags +} + +resource "aws_internet_gateway" "internet_gateway" { + depends_on = [ + aws_vpc.vpc + ] + vpc_id = aws_vpc.vpc.id + tags = local.tags +} + +resource "aws_route" "route" { + depends_on = [ + aws_vpc.vpc, + aws_internet_gateway.internet_gateway + ] + destination_cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.internet_gateway.id + route_table_id = aws_vpc.vpc.main_route_table_id +} + +# Create elastic beanstalk IAM mapping +data "aws_iam_policy_document" "service" { + statement { + actions = [ + "sts:AssumeRole" + ] + principals { + type = "Service" + identifiers = ["elasticbeanstalk.amazonaws.com"] + } + effect = "Allow" + } +} + +resource "aws_iam_role" "service" { + assume_role_policy = data.aws_iam_policy_document.service.json + name = "${var.application_name}-eb-service" +} + +resource "aws_iam_role_policy_attachment" "enhanced_health" { + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkEnhancedHealth" + role = aws_iam_role.service.name +} + +resource "aws_iam_role_policy_attachment" "service" { + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkService" + role = aws_iam_role.service.name +} + +data "aws_iam_policy_document" "ec2" { + statement { + actions = [ + "sts:AssumeRole" + ] + principals { + type = "Service" + identifiers = ["ec2.amazonaws.com"] + } + effect = "Allow" + } + statement { + actions = [ + "sts:AssumeRole", + ] + principals { + type = "Service" + identifiers = ["ssm.amazonaws.com"] + } + effect = "Allow" + } +} + +resource "aws_iam_role" "ec2" { + assume_role_policy = data.aws_iam_policy_document.ec2.json + name = "${var.application_name}-eb-ec2" +} + +resource "aws_iam_instance_profile" "ec2_iam_instance_profile" { + name = "${var.application_name}-iam-instance-profile" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "multicontainer_docker" { + policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "web_tier" { + policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "worker_tier" { + policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkWorkerTier" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "ssm_automation" { + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "ssm_ec2" { + policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "ecr_readonly" { + policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" + role = aws_iam_role.ec2.name +} + +resource "aws_ssm_activation" "ec2" { + depends_on = [ + aws_iam_role.ec2, + aws_iam_role_policy_attachment.ssm_ec2 + ] + name = "${var.application_name}-ec2-activation" + iam_role = aws_iam_role.ec2.id + registration_limit = 3 +} + +data "aws_iam_policy_document" "default" { + statement { + actions = [ + "elasticloadbalancing:DescribeInstanceHealth", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeTargetHealth", + "ec2:DescribeInstances", + "ec2:DescribeInstanceStatus", + "ec2:GetConsoleOutput", + "ec2:AssociateAddress", + "ec2:DescribeAddresses", + "ec2:DescribeSecurityGroups", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeScalingActivities", + "autoscaling:DescribeNotificationConfigurations", + ] + resources = ["*"] + effect = "Allow" + } + + statement { + sid = "AllowOperations" + actions = [ + "autoscaling:AttachInstances", + "autoscaling:CreateAutoScalingGroup", + "autoscaling:CreateLaunchConfiguration", + "autoscaling:DeleteLaunchConfiguration", + "autoscaling:DeleteAutoScalingGroup", + "autoscaling:DeleteScheduledAction", + "autoscaling:DescribeAccountLimits", + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeLaunchConfigurations", + "autoscaling:DescribeLoadBalancers", + "autoscaling:DescribeNotificationConfigurations", + "autoscaling:DescribeScalingActivities", + "autoscaling:DescribeScheduledActions", + "autoscaling:DetachInstances", + "autoscaling:PutScheduledUpdateGroupAction", + "autoscaling:ResumeProcesses", + "autoscaling:SetDesiredCapacity", + "autoscaling:SetInstanceProtection", + "autoscaling:SuspendProcesses", + "autoscaling:TerminateInstanceInAutoScalingGroup", + "autoscaling:UpdateAutoScalingGroup", + "cloudwatch:PutMetricAlarm", + "ec2:AssociateAddress", + "ec2:AllocateAddress", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:AuthorizeSecurityGroupIngress", + "ec2:CreateSecurityGroup", + "ec2:DeleteSecurityGroup", + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeImages", + "ec2:DescribeInstances", + "ec2:DescribeKeyPairs", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSnapshots", + "ec2:DescribeSubnets", + "ec2:DescribeVpcs", + "ec2:DisassociateAddress", + "ec2:ReleaseAddress", + "ec2:RevokeSecurityGroupEgress", + "ec2:RevokeSecurityGroupIngress", + "ec2:TerminateInstances", + "ecs:CreateCluster", + "ecs:DeleteCluster", + "ecs:DescribeClusters", + "ecs:RegisterTaskDefinition", + "elasticbeanstalk:*", + "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer", + "elasticloadbalancing:ConfigureHealthCheck", + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", + "elasticloadbalancing:DescribeInstanceHealth", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:RegisterInstancesWithLoadBalancer", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:DeregisterTargets", + "iam:ListRoles", + "iam:PassRole", + "logs:CreateLogGroup", + "logs:PutRetentionPolicy", + "rds:DescribeDBEngineVersions", + "rds:DescribeDBInstances", + "rds:DescribeOrderableDBInstanceOptions", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:ListBucket", + "sns:CreateTopic", + "sns:GetTopicAttributes", + "sns:ListSubscriptionsByTopic", + "sns:Subscribe", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + "codebuild:CreateProject", + "codebuild:DeleteProject", + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + ] + resources = ["*"] + effect = "Allow" + } + + statement { + sid = "AllowS3OperationsOnElasticBeanstalkBuckets" + actions = [ + "s3:*" + ] + resources = [ + "arn:aws:s3:::*" + ] + effect = "Allow" + } + + statement { + sid = "AllowDeleteCloudwatchLogGroups" + actions = [ + "logs:DeleteLogGroup" + ] + resources = [ + "arn:aws:logs:*:*:log-group:/aws/elasticbeanstalk*" + ] + effect = "Allow" + } + + statement { + sid = "AllowCloudformationOperationsOnElasticBeanstalkStacks" + actions = [ + "cloudformation:*" + ] + resources = [ + "arn:aws:cloudformation:*:*:stack/awseb-*", + "arn:aws:cloudformation:*:*:stack/eb-*" + ] + effect = "Allow" + } +} + +resource "aws_iam_role_policy" "default" { + depends_on = [ + aws_iam_role.ec2 + ] + name = "${var.application_name}-eb-default" + policy = data.aws_iam_policy_document.default.json + role = aws_iam_role.ec2.id +} + +# Create elastic beanstalk Environment +resource "aws_elastic_beanstalk_environment" "environment" { + depends_on = [ + aws_vpc.vpc, + aws_subnet.subnet_a, + aws_subnet.subnet_b, + aws_ssm_activation.ec2 + ] + application = var.environment_application + description = var.environment_description + name = var.environment_name + solution_stack_name = var.environment_solution_stack_name + tier = var.environment_tier + wait_for_ready_timeout = var.environment_wait_for_ready_timeout + version_label = var.environment_version_label + tags = local.tags + + # aws:ec2:instances + setting { + namespace = "aws:ec2:instances" + name = "InstanceTypes" + value = var.instances_instance_types + } + + # aws:ec2:vpc + setting { + namespace = "aws:ec2:vpc" + name = "VPCId" + value = aws_vpc.vpc.id + } + + setting { + namespace = "aws:ec2:vpc" + name = "Subnets" + value = join(",", [aws_subnet.subnet_a.id, aws_subnet.subnet_b.id]) + } + + setting { + namespace = "aws:ec2:vpc" + name = "AssociatePublicIpAddress" + value = var.associate_public_ip_address + } + + setting { + namespace = "aws:elasticbeanstalk:environment" + name = "ServiceRole" + value = aws_iam_role.service.name + } + + # aws:autoscaling:launchconfiguration + setting { + namespace = "aws:autoscaling:launchconfiguration" + name = "IamInstanceProfile" + value = aws_iam_instance_profile.ec2_iam_instance_profile.name + } + + setting { + namespace = "aws:autoscaling:launchconfiguration" + name = "DisableIMDSv1" + value = true + } + + dynamic "setting" { + for_each = local.elb + content { + namespace = setting.value["namespace"] + name = setting.value["name"] + value = setting.value["value"] + } + } + + # aws:autoscaling:updatepolicy:rollingupdate + setting { + namespace = "aws:autoscaling:updatepolicy:rollingupdate" + name = "RollingUpdateEnabled" + value = var.autoscaling_updatepolicy_rolling_update_enabled + } + + setting { + namespace = "aws:autoscaling:updatepolicy:rollingupdate" + name = "RollingUpdateType" + value = var.autoscaling_updatepolicy_rolling_update_type + } + + setting { + namespace = "aws:autoscaling:updatepolicy:rollingupdate" + name = "MinInstancesInService" + value = var.autoscaling_updatepolicy_min_instance_in_service + } + + setting { + namespace = "aws:elasticbeanstalk:application" + name = "Application Healthcheck URL" + value = var.application_healthcheck_url + } + + # aws:elasticbeanstalk:command + setting { + namespace = "aws:elasticbeanstalk:command" + name = "DeploymentPolicy" + value = var.command_deployment_policy + } + + # aws:autoscaling:updatepolicy:rollingupdate + setting { + namespace = "aws:autoscaling:updatepolicy:rollingupdate" + name = "MaxBatchSize" + value = var.updatepolicy_max_batch_size + } + + # aws:elasticbeanstalk:healthreporting:system + setting { + namespace = "aws:elasticbeanstalk:healthreporting:system" + name = "SystemType" + value = var.healthreporting_system_type + } + + # aws:elasticbeanstalk:managedactions + setting { + namespace = "aws:elasticbeanstalk:managedactions" + name = "ManagedActionsEnabled" + value = var.managedactions_managed_actions_enabled ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:managedactions" + name = "PreferredStartTime" + value = var.managedactions_preferred_start_time + } + + # aws:elasticbeanstalk:managedactions:platformupdate + setting { + namespace = "aws:elasticbeanstalk:managedactions:platformupdate" + name = "UpdateLevel" + value = var.managedactions_platformupdate_update_level + } + + setting { + namespace = "aws:elasticbeanstalk:managedactions:platformupdate" + name = "InstanceRefreshEnabled" + value = var.managedactions_platformupdate_instance_refresh_enabled + } + + setting { + namespace = "aws:elasticbeanstalk:command" + name = "IgnoreHealthCheck" + value = var.command_ignore_health_check + } + + # aws:autoscaling:asg + setting { + namespace = "aws:autoscaling:asg" + name = "MinSize" + value = var.autoscaling_asg_minsize + } + setting { + namespace = "aws:autoscaling:asg" + name = "MaxSize" + value = var.autoscaling_asg_maxsize + } + + # aws:autoscaling:trigger + setting { + namespace = "aws:autoscaling:trigger" + name = "MeasureName" + value = var.autoscaling_trigger_measure_name + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "Statistic" + value = var.autoscaling_trigger_statistic + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "Unit" + value = var.autoscaling_trigger_unit + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "LowerThreshold" + value = var.autoscaling_trigger_lower_threshold + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "LowerBreachScaleIncrement" + value = var.autoscaling_trigger_lower_breach_scale_increment + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "UpperThreshold" + value = var.autoscaling_trigger_upper_threshold + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "UpperBreachScaleIncrement" + value = var.autoscaling_trigger_upper_breach_scale_increment + } + + # aws:elasticbeanstalk:hostmanager + setting { + namespace = "aws:elasticbeanstalk:hostmanager" + name = "LogPublicationControl" + value = var.hostmanager_log_publication_control ? "true" : "false" + } + + # aws:elasticbeanstalk:cloudwatch:logs + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs" + name = "StreamLogs" + value = var.cloudwatch_logs_stream_logs ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs" + name = "DeleteOnTerminate" + value = var.cloudwatch_logs_delete_on_terminate ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs" + name = "RetentionInDays" + value = var.cloudwatch_logs_retention_in_days + } + + # aws:elasticbeanstalk:cloudwatch:logs:health + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs:health" + name = "HealthStreamingEnabled" + value = var.cloudwatch_logs_health_health_streaming_enabled ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs:health" + name = "DeleteOnTerminate" + value = var.cloudwatch_logs_health_delete_on_terminate ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs:health" + name = "RetentionInDays" + value = var.cloudwatch_logs_health_retention_in_days + } + + # aws:elasticbeanstalk:application:environment + dynamic "setting" { + for_each = var.environment_variables + content { + namespace = "aws:elasticbeanstalk:application:environment" + name = setting.key + value = setting.value + } + } +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/output.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/output.tf new file mode 100644 index 0000000000..de7cdae87b --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/output.tf @@ -0,0 +1,7 @@ +output "environment_cname" { + value = aws_elastic_beanstalk_environment.environment.cname +} + +output "environment_name" { + value = aws_elastic_beanstalk_environment.environment.name +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/variables.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/variables.tf new file mode 100644 index 0000000000..a442215a9e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/variables.tf @@ -0,0 +1,410 @@ +# Variables for elastic beanstalk VPC +variable "vpc_cidr_block" { + description = "The CIDR block for the association." + type = string + default = "10.0.0.0/16" +} + +variable "vpc_enable_dns_hostnames" { + description = "Whether or not the VPC has DNS hostname support." + type = bool + default = true +} + +variable "vpc_enable_dns_support" { + description = "Whether or not the VPC has DNS support." + type = bool + default = true +} + +variable "vpc_instance_tenancy" { + description = "The allowed tenancy of instances launched into the selected VPC." + type = string + default = "default" +} + +# Variables for elastic beanstalk Subnet +variable "subnet_a_availability_zone" { + description = "AZ for the subnet." + type = string + default = "us-east-1a" +} + +variable "subnet_a_cidr_block" { + description = "The IPv4 CIDR block for the subnet." + type = string + default = "10.0.0.0/20" +} + +variable "subnet_b_availability_zone" { + description = "AZ for the subnet." + type = string + default = "us-east-1b" +} + +variable "subnet_b_cidr_block" { + description = "The IPv4 CIDR block for the subnet." + type = string + default = "10.0.16.0/20" +} + +# Variables for elastic beanstalk Application +variable "environment_application" { + description = "The name of the application, must be unique within account." + type = string + default = "Beanstalk Application" +} + +variable "application_description" { + description = "Short description of the application." + type = string + default = "Beanstalk Application" +} + +variable "application_name" { + description = "The name of the application, must be unique within account." + type = string + default = "Beanstalk" +} + +variable "appversion_lifecycle_service_role_arn" { + description = "The service role ARN to use for application version cleanup. If left empty, the `appversion_lifecycle` block will not be created." + type = string + default = "" +} + +variable "appversion_lifecycle_max_count" { + description = "The max number of application versions to keep" + type = number + default = 2 +} + +variable "appversion_lifecycle_delete_source_from_s3" { + description = "Whether to delete application versions from S3 source" + type = bool + default = false +} + +# Variables for elastic beanstalk Environment +variable "environment_description" { + description = "Short description of the environment." + type = string + default = "Beanstalk Environment" +} + +variable "environment_name" { + description = "A unique name for this Environment. This name is used in the application URL." + type = string + default = "Beanstalk-env" +} + +variable "environment_solution_stack_name" { + description = "A solution stack to base your environment off of." + type = string + default = "64bit Amazon Linux 2 v3.3.11 running Python 3.8" +} + +variable "environment_tier" { + description = "The environment tier specified." + type = string + default = "WebServer" +} + +variable "environment_wait_for_ready_timeout" { + description = "The maximum duration to wait for the Elastic Beanstalk Environment to be in a ready state before timing out" + type = string + default = "20m" +} + +variable "environment_version_label" { + description = "The name of the Elastic Beanstalk Application Version to use in deployment." + type = string + default = "" +} + +# aws:ec2:instances +variable "instances_instance_types" { + description = "Instances type" + type = string + default = "t3.medium" +} + +# aws:ec2:vpc +variable "associate_public_ip_address" { + description = "Whether to associate public IP addresses to the instances." + type = bool + default = true +} + +variable "elb_scheme" { + description = "Specify `internal` if you want to create an internal load balancer in your Amazon VPC so that your Elastic Beanstalk application cannot be accessed from outside your Amazon VPC." + type = string + default = "public" +} + +# aws:elbv2:listener:default +variable "default_listener_enabled" { + description = "Set to false to disable the listener. You can use this option to disable the default listener on port 80." + type = bool + default = true +} + +# aws:elasticbeanstalk:environment +variable "environment_loadbalancer_type" { + description = "Load Balancer type, e.g. 'application' or 'classic'." + type = string + default = "classic" +} + +variable "environment_loadbalancer_security_groups" { + description = "Load balancer security groups" + type = list(string) + default = [] +} + +variable "environment_loadbalancer_managed_security_group" { + description = "Load balancer managed security group" + type = string + default = "" +} + +variable "environment_loadbalancer_ssl_certificate_id" { + type = string + default = "" + description = "Load Balancer SSL certificate ARN. The certificate must be present in AWS Certificate Manager" +} + +# aws:elasticbeanstalk:environment:process:default +variable "environment_process_default_healthcheck_interval" { + description = "The interval of time, in seconds, that Elastic Load Balancing checks the health of the Amazon EC2 instances of your application." + type = number + default = 10 +} + +variable "environment_process_default_healthy_threshold_count" { + description = "The number of consecutive successful requests before Elastic Load Balancing changes the instance health status." + type = number + default = 3 +} + +variable "environment_process_default_port" { + description = "Port application is listening on." + type = number + default = 5000 +} + +variable "environment_process_default_unhealthy_threshold_count" { + description = "The number of consecutive unsuccessful requests before Elastic Load Balancing changes the instance health status." + type = number + default = 3 +} + +# aws:autoscaling:updatepolicy:rollingupdate +variable "autoscaling_updatepolicy_rolling_update_enabled" { + description = "Whether to enable rolling update." + type = bool + default = true +} + +variable "autoscaling_updatepolicy_rolling_update_type" { + description = "`Health` or `Immutable`. Set it to `Immutable` to apply the configuration change to a fresh group of instances." + type = string + default = "Immutable" +} + +variable "autoscaling_updatepolicy_min_instance_in_service" { + description = "Minimum number of instances in service during update." + type = number + default = 1 +} + +variable "application_healthcheck_url" { + description = "The path where health check requests are sent to." + type = string + default = "/" +} + +variable "environment_listener_ssl_policy" { + description = "Specify a security policy to apply to the listener. This option is only applicable to environments with an application load balancer." + type = string + default = "" +} + +variable "default_matcher_http_code" { + description = "List of HTTP codes that indicate that an instance is healthy. Note that this option is only applicable to environments with a network or application load balancer." + type = list(string) + default = ["200"] +} + +variable "default_health_check_timeout" { + description = "The amount of time, in seconds, to wait for a response during a health check. Note that this option is only applicable to environments with an application load balancer" + type = number + default = 5 +} + +# aws:elasticbeanstalk:command +variable "command_deployment_policy" { + description = "Use the DeploymentPolicy option to set the deployment type. The following values are supported: `AllAtOnce`, `Rolling`, `RollingWithAdditionalBatch`, `Immutable`, `TrafficSplitting`." + type = string + default = "Rolling" +} + +# aws:autoscaling:updatepolicy:rollingupdate +variable "updatepolicy_max_batch_size" { + description = "Maximum number of instances to update at once." + type = number + default = 1 +} + +# aws:elasticbeanstalk:healthreporting:system +variable "healthreporting_system_type" { + description = "Whether to enable enhanced health reporting for this environment" + type = string + default = "enhanced" +} + +# aws:elasticbeanstalk:managedactions +variable "managedactions_managed_actions_enabled" { + description = "Enable managed platform updates. When you set this to true, you must also specify a `PreferredStartTime` and `UpdateLevel`" + type = bool + default = true +} + +variable "managedactions_preferred_start_time" { + description = "Configure a maintenance window for managed actions in UTC" + type = string + default = "Sun:10:00" +} + +# aws:elasticbeanstalk:managedactions:platformupdate +variable "managedactions_platformupdate_update_level" { + description = "The highest level of update to apply with managed platform updates" + type = string + default = "minor" +} + +variable "managedactions_platformupdate_instance_refresh_enabled" { + description = "Enable weekly instance replacement." + type = bool + default = true +} + +variable "command_ignore_health_check" { + description = "Do not cancel a deployment due to failed health checks" + type = bool + default = true +} + +# aws:autoscaling:asg +variable "autoscaling_asg_minsize" { + description = "Minumum instances to launch" + type = number + default = 1 +} + +variable "autoscaling_asg_maxsize" { + description = "Maximum instances to launch" + type = number + default = 2 +} + +# aws:autoscaling:trigger +variable "autoscaling_trigger_measure_name" { + description = "Metric used for your Auto Scaling trigger" + type = string + default = "CPUUtilization" +} + +variable "autoscaling_trigger_statistic" { + description = "Statistic the trigger should use, such as Average" + type = string + default = "Average" +} + +variable "autoscaling_trigger_unit" { + description = "Unit for the trigger measurement, such as Bytes" + type = string + default = "Percent" +} + +variable "autoscaling_trigger_lower_threshold" { + description = "Minimum level of autoscale metric to remove an instance" + type = number + default = 20 +} + +variable "autoscaling_trigger_lower_breach_scale_increment" { + description = "How many Amazon EC2 instances to remove when performing a scaling activity." + type = number + default = -1 +} + +variable "autoscaling_trigger_upper_threshold" { + description = "Maximum level of autoscale metric to add an instance" + type = number + default = 80 +} + +variable "autoscaling_trigger_upper_breach_scale_increment" { + description = "How many Amazon EC2 instances to add when performing a scaling activity" + type = number + default = 1 +} + +# aws:elasticbeanstalk:hostmanager +variable "hostmanager_log_publication_control" { + description = "Copy the log files for your application's Amazon EC2 instances to the Amazon S3 bucket associated with your application" + type = bool + default = true +} + +# aws:elasticbeanstalk:cloudwatch:logs +variable "cloudwatch_logs_stream_logs" { + description = "Whether to create groups in CloudWatch Logs for proxy and deployment logs, and stream logs from each instance in your environment" + type = bool + default = true +} + +variable "cloudwatch_logs_delete_on_terminate" { + description = "Whether to delete the log groups when the environment is terminated. If false, the logs are kept RetentionInDays days" + type = bool + default = true +} + +variable "cloudwatch_logs_retention_in_days" { + description = "The number of days to keep log events before they expire." + type = number + default = 3 +} + +# aws:elasticbeanstalk:cloudwatch:logs:health +variable "cloudwatch_logs_health_health_streaming_enabled" { + description = "For environments with enhanced health reporting enabled, whether to create a group in CloudWatch Logs for environment health and archive Elastic Beanstalk environment health data. For information about enabling enhanced health, see aws:elasticbeanstalk:healthreporting:system." + type = bool + default = true +} + +variable "cloudwatch_logs_health_delete_on_terminate" { + description = "Whether to delete the log group when the environment is terminated. If false, the health data is kept RetentionInDays days." + type = bool + default = true +} + +variable "cloudwatch_logs_health_retention_in_days" { + description = "The number of days to keep the archived health data before it expires." + type = number + default = 3 +} + +variable "environment_type" { + description = "Environment type, e.g. 'LoadBalanced' or 'SingleInstance'. If setting to 'SingleInstance', `rolling_update_type` must be set to 'Time', `updating_min_in_service` must be set to 0, and `loadbalancer_subnets` will be unused (it applies to the ELB, which does not exist in SingleInstance environments)." + type = string + default = "LoadBalanced" +} + +# aws:elasticbeanstalk:application:environment +variable "environment_variables" { + description = "Map of custom ENV variables to be provided to the application." + type = map(string) + default = {} +} diff --git a/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/versions.tf b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/versions.tf new file mode 100644 index 0000000000..5aa6f2519e --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-elastic-beanstalk-environment/versions.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.7.0" + } + vault = { + version = ">= 3.2.1" + } + } + required_version = ">= 1.5.4" +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/main.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/main.tf new file mode 100644 index 0000000000..7eb5ea59b9 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/main.tf @@ -0,0 +1,21 @@ +locals { + bucket = var.application_bucket + description = var.application_description + name = var.application_name + name_version = "${var.application_name}-base-1.${var.application_version}" + source = var.application_source +} + +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault_name}-path" + role = "${var.vault_name}-role" +} + +module "elastic_beanstalk_application_version" { + source = "../terraform-aws-elastic-beanstalk-application-version" + application_bucket = local.bucket + application_description = local.description + application_name = local.name + application_name_version = local.name_version + application_source = local.source +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/output.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/output.tf new file mode 100644 index 0000000000..0126e7a9c7 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/output.tf @@ -0,0 +1,3 @@ +output "application_version" { + value = module.elastic_beanstalk_application_version.application_version +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/providers.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/providers.tf new file mode 100644 index 0000000000..7241b27c16 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = var.vault_provider_address + skip_tls_verify = var.vault_provider_skip_tls_verify + token = var.vault_provider_token +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/variables.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/variables.tf new file mode 100644 index 0000000000..653a92b970 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/variables.tf @@ -0,0 +1,58 @@ +variable "region" { + description = "AWS Region." + type = string + default = "eu-north-1" +} + +variable "vault_provider_address" { + description = "Vault cluster address." + type = string + default = "http://10.30.51.24:8200" +} + +variable "vault_provider_skip_tls_verify" { + description = "Verification of the Vault server's TLS certificate." + type = bool + default = false +} + +variable "vault_provider_token" { + description = "Vault root token." + type = string + default = "s.4z5PsufFwV3sHbCzK9Y2Cojd" +} + +variable "vault_name" { + type = string + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} + +variable "application_bucket" { + description = "The name of the bucket." + type = string + default = "elasticbeanstalk-eu-north-1-407116685360" +} + +variable "application_description" { + description = "Short description of the Application Version." + type = string + default = "FD.io CDASH" +} + +variable "application_name" { + description = "Name of the Beanstalk Application." + type = string + default = "fdio-csit-dash-app-m7g" +} + +variable "application_source" { + description = "The source file with application code." + type = string + default = "../../csit.infra.dash/app.zip" +} + +variable "application_version" { + description = "Application version string." + type = number + default = 1 +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/versions.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/versions.tf new file mode 100644 index 0000000000..cd4761e34c --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-app-base/versions.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.31.0" + } + vault = { + version = ">= 3.23.0" + } + } + required_version = ">= 1.4.2" +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/main.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/main.tf new file mode 100644 index 0000000000..9f115cd6c6 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/main.tf @@ -0,0 +1,124 @@ +data "vault_generic_secret" "fdio_docs" { + path = "kv/secret/data/etl/fdio_docs" +} + +data "vault_aws_access_credentials" "creds" { + backend = "${var.vault_name}-path" + role = "${var.vault_name}-role" +} + +module "elastic_beanstalk_application" { + source = "../terraform-aws-elastic-beanstalk-application" + + # application + application_description = "FD.io CDASH M7G" + application_name = "fdio-csit-dash-app-m7g" + appversion_lifecycle_service_role_arn = "arn:aws:iam::407116685360:role/aws-service-role/elasticbeanstalk.amazonaws.com/AWSServiceRoleForElasticBeanstalk" + appversion_lifecycle_max_count = 10 + appversion_lifecycle_delete_source_from_s3 = false +} + +module "elastic_beanstalk_environment" { + source = "../terraform-aws-elastic-beanstalk-environment" + + # environment + application_name = "fdio-csit-dash-app-m7g" + + # vpc + vpc_cidr_block = "10.0.0.0/16" + vpc_enable_dns_hostnames = true + vpc_enable_dns_support = true + vpc_instance_tenancy = "default" + + # subnet + subnet_a_availability_zone = "eu-north-1a" + subnet_a_cidr_block = "10.0.0.0/20" + subnet_b_availability_zone = "eu-north-1b" + subnet_b_cidr_block = "10.0.16.0/20" + + # environment + environment_application = module.elastic_beanstalk_application.application_name + environment_description = module.elastic_beanstalk_application.application_description + environment_name = "fdio-csit-dash-env-m7g" + environment_solution_stack_name = "64bit Amazon Linux 2023 v4.0.6 running Python 3.11" + environment_tier = "WebServer" + environment_wait_for_ready_timeout = "25m" + environment_version_label = "" + + # aws:ec2:instances + instances_instance_types = "m7g.2xlarge" + + # aws:ec2:vpc + associate_public_ip_address = true + elb_scheme = "public" + + # aws:elbv2:listener:default + default_listener_enabled = true + + # aws:elasticbeanstalk:environment + environment_loadbalancer_type = "application" + environment_loadbalancer_ssl_certificate_id = "arn:aws:acm:eu-north-1:407116685360:certificate/3ef3c6ae-f1d4-49f0-a8cd-5d090991bf73" + + # aws:elasticbeanstalk:environment:process:default + environment_process_default_healthcheck_interval = 10 + environment_process_default_healthy_threshold_count = 3 + environment_process_default_port = 5000 + environment_process_default_unhealthy_threshold_count = 3 + + # aws:autoscaling:updatepolicy:rollingupdate + autoscaling_updatepolicy_rolling_update_enabled = true + autoscaling_updatepolicy_rolling_update_type = "Immutable" + autoscaling_updatepolicy_min_instance_in_service = 1 + + # aws:elasticbeanstalk:command + command_deployment_policy = "Rolling" + + # aws:autoscaling:updatepolicy:rollingupdate + updatepolicy_max_batch_size = 1 + + # aws:elasticbeanstalk:healthreporting:system + healthreporting_system_type = "enhanced" + + # aws:elasticbeanstalk:managedactions + managedactions_managed_actions_enabled = true + managedactions_preferred_start_time = "Sun:10:00" + + # aws:elasticbeanstalk:managedactions:platformupdate + managedactions_platformupdate_update_level = "minor" + managedactions_platformupdate_instance_refresh_enabled = true + + # aws:autoscaling:asg + autoscaling_asg_minsize = 1 + autoscaling_asg_maxsize = 2 + + # aws:autoscaling:trigger + autoscaling_trigger_measure_name = "CPUUtilization" + autoscaling_trigger_statistic = "Average" + autoscaling_trigger_unit = "Percent" + autoscaling_trigger_lower_threshold = 20 + autoscaling_trigger_lower_breach_scale_increment = -1 + autoscaling_trigger_upper_threshold = 80 + autoscaling_trigger_upper_breach_scale_increment = 1 + + # aws:elasticbeanstalk:hostmanager + hostmanager_log_publication_control = true + + # aws:elasticbeanstalk:cloudwatch:logs + cloudwatch_logs_stream_logs = true + cloudwatch_logs_delete_on_terminate = true + cloudwatch_logs_retention_in_days = 3 + + # aws:elasticbeanstalk:cloudwatch:logs:health + cloudwatch_logs_health_health_streaming_enabled = true + cloudwatch_logs_health_delete_on_terminate = true + cloudwatch_logs_health_retention_in_days = 3 + + environment_type = "LoadBalanced" + + # aws:elasticbeanstalk:application:environment + environment_variables = { + "AWS_ACCESS_KEY_ID" = data.vault_generic_secret.fdio_docs.data["access_key"] + "AWS_SECRET_ACCESS_KEY" = data.vault_generic_secret.fdio_docs.data["secret_key"] + "AWS_DEFAULT_REGION" = data.vault_generic_secret.fdio_docs.data["region"] + } +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/output.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/output.tf new file mode 100644 index 0000000000..094c8f5422 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/output.tf @@ -0,0 +1,4 @@ +output "elastic_beanstalk_environment_hostname" { + description = "DNS hostname" + value = module.elastic_beanstalk_environment.environment_cname +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/providers.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/providers.tf new file mode 100644 index 0000000000..7241b27c16 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/providers.tf @@ -0,0 +1,11 @@ +provider "aws" { + region = var.region + access_key = data.vault_aws_access_credentials.creds.access_key + secret_key = data.vault_aws_access_credentials.creds.secret_key +} + +provider "vault" { + address = var.vault_provider_address + skip_tls_verify = var.vault_provider_skip_tls_verify + token = var.vault_provider_token +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/variables.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/variables.tf new file mode 100644 index 0000000000..d7ff1d19ff --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/variables.tf @@ -0,0 +1,28 @@ +variable "region" { + description = "AWS Region." + type = string + default = "eu-north-1" +} + +variable "vault_provider_address" { + description = "Vault cluster address." + type = string + default = "http://10.30.51.24:8200" +} + +variable "vault_provider_skip_tls_verify" { + description = "Verification of the Vault server's TLS certificate." + type = bool + default = false +} + +variable "vault_provider_token" { + description = "Vault root token." + type = string + sensitive = true +} + +variable "vault_name" { + type = string + default = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} diff --git a/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/versions.tf b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/versions.tf new file mode 100644 index 0000000000..153890e01b --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-fdio-csit-dash-env/versions.tf @@ -0,0 +1,17 @@ +terraform { + backend "consul" { + address = "10.30.51.24:8500" + scheme = "http" + path = "terraform/dash_m7g" + } + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.31.0" + } + vault = { + version = ">= 3.23.0" + } + } + required_version = ">= 1.4.2" +} diff --git a/fdio.infra.terraform/terraform-aws-subnet/README.md b/fdio.infra.terraform/terraform-aws-subnet/README.md new file mode 100644 index 0000000000..54986d1ddb --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/README.md @@ -0,0 +1,44 @@ +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.4 | +| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 4.3.0 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 4.3.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_subnet.subnet](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_vpc_ipv4_cidr_block_association.ipv4_cidr_block_association](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipv4_cidr_block_association) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_subnet_assign_ipv6_address_on_creation"></a> [subnet\_assign\_ipv6\_address\_on\_creation](#input\_subnet\_assign\_ipv6\_address\_on\_creation) | Specify true to indicate that network interfaces created in the specified subnet should be assigned an IPv6 address. | `bool` | `false` | no | +| <a name="input_subnet_availability_zone"></a> [subnet\_availability\_zone](#input\_subnet\_availability\_zone) | AZ for the subnet. | `string` | `"us-east-1a"` | no | +| <a name="input_subnet_cidr_block"></a> [subnet\_cidr\_block](#input\_subnet\_cidr\_block) | The IPv4 CIDR block for the subnet. | `string` | n/a | yes | +| <a name="input_subnet_ipv6_cidr_block"></a> [subnet\_ipv6\_cidr\_block](#input\_subnet\_ipv6\_cidr\_block) | The IPv6 network range for the subnet, in CIDR notation. | `string` | n/a | yes | +| <a name="input_subnet_map_public_ip_on_launch"></a> [subnet\_map\_public\_ip\_on\_launch](#input\_subnet\_map\_public\_ip\_on\_launch) | Specify true to indicate that instances launched into the subnet should be assigned a public IP address. | `bool` | `false` | no | +| <a name="input_subnet_vpc_id"></a> [subnet\_vpc\_id](#input\_subnet\_vpc\_id) | The VPC ID. | `string` | n/a | yes | +| <a name="input_tags_environment"></a> [tags\_environment](#input\_tags\_environment) | Environment used for tag. | `string` | `""` | no | +| <a name="input_tags_name"></a> [tags\_name](#input\_tags\_name) | Name used for tag. | `string` | `""` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| <a name="output_subnet_id"></a> [subnet\_id](#output\_subnet\_id) | The ID of the Subnet | +<!-- END_TF_DOCS -->
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-subnet/example/main.tf b/fdio.infra.terraform/terraform-aws-subnet/example/main.tf new file mode 100644 index 0000000000..98f8613876 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/example/main.tf @@ -0,0 +1,17 @@ +module "vpc" { + source = "../../terraform-aws-vpc" + security_group_name = "terraform-sg" + subnet_availability_zone = "us-east-1a" + tags_name = "terraform-vpc" + tags_environment = "terraform-vpc-environment" +} + +module "subnet" { + source = "../" + subnet_cidr_block = "192.168.10.0/24" + subnet_ipv6_cidr_block = cidrsubnet(module.vpc.vpc_ipv6_cidr_block, 8, 1) + subnet_availability_zone = "us-east-1a" + tags_name = "terraform-subnet" + tags_environment = "terraform-subnet-environment" + subnet_vpc_id = module.vpc.vpc_id +} diff --git a/fdio.infra.terraform/terraform-aws-subnet/example/output.tf b/fdio.infra.terraform/terraform-aws-subnet/example/output.tf new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/example/output.tf diff --git a/fdio.infra.terraform/terraform-aws-subnet/example/providers.tf b/fdio.infra.terraform/terraform-aws-subnet/example/providers.tf new file mode 100644 index 0000000000..5ff54f0d65 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/example/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = var.region +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-subnet/example/variables.tf b/fdio.infra.terraform/terraform-aws-subnet/example/variables.tf new file mode 100644 index 0000000000..f75f3d547f --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/example/variables.tf @@ -0,0 +1,5 @@ +variable "region" { + description = "AWS Region." + type = string + default = "us-east-1" +} diff --git a/fdio.infra.terraform/terraform-aws-subnet/example/versions.tf b/fdio.infra.terraform/terraform-aws-subnet/example/versions.tf new file mode 100644 index 0000000000..7afde83d1b --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/example/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.1.0" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-subnet/main.tf b/fdio.infra.terraform/terraform-aws-subnet/main.tf new file mode 100644 index 0000000000..d14aa5f827 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/main.tf @@ -0,0 +1,26 @@ +locals { + tags = { + "Name" = "${var.tags_name}" + "Environment" = "${var.tags_environment}" + } +} + +# Create VPC IPv4 CIDR Block Association +resource "aws_vpc_ipv4_cidr_block_association" "ipv4_cidr_block_association" { + cidr_block = var.subnet_cidr_block + vpc_id = var.subnet_vpc_id +} + +# Create Subnet +resource "aws_subnet" "subnet" { + depends_on = [ + aws_vpc_ipv4_cidr_block_association.ipv4_cidr_block_association + ] + assign_ipv6_address_on_creation = var.subnet_assign_ipv6_address_on_creation + availability_zone = var.subnet_availability_zone + cidr_block = var.subnet_cidr_block + ipv6_cidr_block = var.subnet_ipv6_cidr_block + map_public_ip_on_launch = var.subnet_map_public_ip_on_launch + tags = local.tags + vpc_id = var.subnet_vpc_id +} diff --git a/fdio.infra.terraform/terraform-aws-subnet/outputs.tf b/fdio.infra.terraform/terraform-aws-subnet/outputs.tf new file mode 100644 index 0000000000..7f17d95717 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/outputs.tf @@ -0,0 +1,4 @@ +output "subnet_id" { + value = aws_subnet.subnet.id + description = "The ID of the Subnet" +} diff --git a/fdio.infra.terraform/terraform-aws-subnet/variables.tf b/fdio.infra.terraform/terraform-aws-subnet/variables.tf new file mode 100644 index 0000000000..c0e1fad157 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/variables.tf @@ -0,0 +1,45 @@ +variable "tags_name" { + description = "Name used for tag." + type = string + default = "" +} + +variable "tags_environment" { + description = "Environment used for tag." + type = string + default = "" +} + +# Variables for Subnet +variable "subnet_assign_ipv6_address_on_creation" { + description = "Specify true to indicate that network interfaces created in the specified subnet should be assigned an IPv6 address." + type = bool + default = true +} + +variable "subnet_availability_zone" { + description = "AZ for the subnet." + type = string + default = "us-east-1a" +} + +variable "subnet_cidr_block" { + description = "The IPv4 CIDR block for the subnet." + type = string +} + +variable "subnet_ipv6_cidr_block" { + description = "The IPv6 network range for the subnet, in CIDR notation." + type = string +} + +variable "subnet_map_public_ip_on_launch" { + description = "Specify true to indicate that instances launched into the subnet should be assigned a public IP address." + type = bool + default = false +} + +variable "subnet_vpc_id" { + description = "The VPC ID." + type = string +} diff --git a/fdio.infra.terraform/terraform-aws-subnet/versions.tf b/fdio.infra.terraform/terraform-aws-subnet/versions.tf new file mode 100644 index 0000000000..7afde83d1b --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-subnet/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.1.0" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-vpc/README.md b/fdio.infra.terraform/terraform-aws-vpc/README.md new file mode 100644 index 0000000000..52f6d1cfc7 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/README.md @@ -0,0 +1,58 @@ +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.4 | +| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 4.3.0 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 4.3.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_internet_gateway.internet_gateway](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource | +| [aws_route.route](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource | +| [aws_security_group.security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | +| [aws_subnet.subnet](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource | +| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_security_group_description"></a> [security\_group\_description](#input\_security\_group\_description) | Security group description. | `string` | `"Allow inbound/outbound traffic"` | no | +| <a name="input_security_group_egress"></a> [security\_group\_egress](#input\_security\_group\_egress) | Egress security group map. | `list(any)` | <pre>[<br> {<br> "cidr_blocks": [<br> "0.0.0.0/0"<br> ],<br> "from_port": 0,<br> "ipv6_cidr_blocks": [<br> "::/0"<br> ],<br> "protocol": "-1",<br> "to_port": 0<br> }<br>]</pre> | no | +| <a name="input_security_group_ingress"></a> [security\_group\_ingress](#input\_security\_group\_ingress) | Ingress security group map. | `list(any)` | <pre>[<br> {<br> "cidr_blocks": [<br> "0.0.0.0/0"<br> ],<br> "from_port": 22,<br> "ipv6_cidr_blocks": [<br> "::/0"<br> ],<br> "protocol": "tcp",<br> "self": false,<br> "to_port": 22<br> },<br> {<br> "cidr_blocks": [<br> "0.0.0.0/0"<br> ],<br> "from_port": 0,<br> "ipv6_cidr_blocks": [<br> "::/0"<br> ],<br> "protocol": -1,<br> "self": true,<br> "to_port": 0<br> }<br>]</pre> | no | +| <a name="input_security_group_name"></a> [security\_group\_name](#input\_security\_group\_name) | Name of the security group. | `string` | n/a | yes | +| <a name="input_security_group_revoke_rules_on_delete"></a> [security\_group\_revoke\_rules\_on\_delete](#input\_security\_group\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself. | `bool` | `false` | no | +| <a name="input_subnet_assign_ipv6_address_on_creation"></a> [subnet\_assign\_ipv6\_address\_on\_creation](#input\_subnet\_assign\_ipv6\_address\_on\_creation) | Specify true to indicate that network interfaces created in the specified subnet should be assigned an IPv6 address. | `bool` | `false` | no | +| <a name="input_subnet_availability_zone"></a> [subnet\_availability\_zone](#input\_subnet\_availability\_zone) | AWS availability zone | `string` | `"us-east-1a"` | no | +| <a name="input_subnet_map_public_ip_on_launch"></a> [subnet\_map\_public\_ip\_on\_launch](#input\_subnet\_map\_public\_ip\_on\_launch) | Specify true to indicate that instances launched into the subnet should be assigned a public IP address. | `bool` | `false` | no | +| <a name="input_tags_environment"></a> [tags\_environment](#input\_tags\_environment) | Environment used for tag. | `string` | `""` | no | +| <a name="input_tags_name"></a> [tags\_name](#input\_tags\_name) | Name used for tag. | `string` | `""` | no | +| <a name="input_vpc_assign_generated_ipv6_cidr_block"></a> [vpc\_assign\_generated\_ipv6\_cidr\_block](#input\_vpc\_assign\_generated\_ipv6\_cidr\_block) | Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC. | `bool` | `true` | no | +| <a name="input_vpc_cidr_block"></a> [vpc\_cidr\_block](#input\_vpc\_cidr\_block) | The CIDR block for the association. | `string` | `"192.168.0.0/24"` | no | +| <a name="input_vpc_enable_dns_hostnames"></a> [vpc\_enable\_dns\_hostnames](#input\_vpc\_enable\_dns\_hostnames) | Whether or not the VPC has DNS hostname support. | `bool` | `true` | no | +| <a name="input_vpc_enable_dns_support"></a> [vpc\_enable\_dns\_support](#input\_vpc\_enable\_dns\_support) | Whether or not the VPC has DNS support. | `bool` | `true` | no | +| <a name="input_vpc_instance_tenancy"></a> [vpc\_instance\_tenancy](#input\_vpc\_instance\_tenancy) | The allowed tenancy of instances launched into the selected VPC. | `string` | `"default"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| <a name="output_vpc_id"></a> [vpc\_id](#output\_vpc\_id) | The ID of the VPC. | +| <a name="output_vpc_ipv6_cidr_block"></a> [vpc\_ipv6\_cidr\_block](#output\_vpc\_ipv6\_cidr\_block) | IPv6 CIDR block. | +| <a name="output_vpc_main_route_table_id"></a> [vpc\_main\_route\_table\_id](#output\_vpc\_main\_route\_table\_id) | The ID of the Main Route Table. | +| <a name="output_vpc_security_group_id"></a> [vpc\_security\_group\_id](#output\_vpc\_security\_group\_id) | The ID of the Security Group. | +| <a name="output_vpc_subnet_id"></a> [vpc\_subnet\_id](#output\_vpc\_subnet\_id) | The ID of the Subnet. | +<!-- END_TF_DOCS -->
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-vpc/example/main.tf b/fdio.infra.terraform/terraform-aws-vpc/example/main.tf new file mode 100644 index 0000000000..9d9469754d --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/example/main.tf @@ -0,0 +1,7 @@ +module "vpc" { + source = "../" + security_group_name = "terraform-sg" + subnet_availability_zone = "us-east-1a" + tags_name = "terraform-vpc" + tags_environment = "terraform-vpc-environment" +} diff --git a/fdio.infra.terraform/terraform-aws-vpc/example/output.tf b/fdio.infra.terraform/terraform-aws-vpc/example/output.tf new file mode 100644 index 0000000000..c26bbaecb6 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/example/output.tf @@ -0,0 +1,4 @@ +output "vpc_id" { + value = module.vpc.vpc_id + description = "The ID of the VPC" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-vpc/example/providers.tf b/fdio.infra.terraform/terraform-aws-vpc/example/providers.tf new file mode 100644 index 0000000000..5ff54f0d65 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/example/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = var.region +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-vpc/example/variables.tf b/fdio.infra.terraform/terraform-aws-vpc/example/variables.tf new file mode 100644 index 0000000000..f75f3d547f --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/example/variables.tf @@ -0,0 +1,5 @@ +variable "region" { + description = "AWS Region." + type = string + default = "us-east-1" +} diff --git a/fdio.infra.terraform/terraform-aws-vpc/example/versions.tf b/fdio.infra.terraform/terraform-aws-vpc/example/versions.tf new file mode 100644 index 0000000000..7afde83d1b --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/example/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.1.0" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-aws-vpc/main.tf b/fdio.infra.terraform/terraform-aws-vpc/main.tf new file mode 100644 index 0000000000..1b84f8e351 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/main.tf @@ -0,0 +1,93 @@ +locals { + tags = { + "Name" = "${var.tags_name}" + "Environment" = "${var.tags_environment}" + } +} + +# Create VPC +resource "aws_vpc" "vpc" { + assign_generated_ipv6_cidr_block = var.vpc_assign_generated_ipv6_cidr_block + cidr_block = var.vpc_cidr_block + enable_dns_hostnames = var.vpc_enable_dns_hostnames + enable_dns_support = var.vpc_enable_dns_support + instance_tenancy = var.vpc_instance_tenancy + tags = local.tags +} + +# Create Security Group +resource "aws_security_group" "security_group" { + depends_on = [ + aws_vpc.vpc + ] + description = var.security_group_description + name = var.security_group_name + revoke_rules_on_delete = var.security_group_revoke_rules_on_delete + tags = local.tags + vpc_id = aws_vpc.vpc.id + + ingress { + from_port = 0 + to_port = 0 + protocol = -1 + self = true + ipv6_cidr_blocks = ["::/0"] + } + + dynamic "ingress" { + for_each = var.security_group_ingress + content { + from_port = lookup(ingress.value, "from_port", null) + to_port = lookup(ingress.value, "to_port", null) + protocol = lookup(ingress.value, "protocol", null) + self = lookup(ingress.value, "self", null) + cidr_blocks = lookup(ingress.value, "cidr_blocks", null) + ipv6_cidr_blocks = lookup(ingress.value, "ipv6_cidr_blocks", null) + } + } + dynamic "egress" { + for_each = var.security_group_egress + content { + from_port = lookup(egress.value, "from_port", null) + to_port = lookup(egress.value, "to_port", null) + protocol = lookup(egress.value, "protocol", null) + self = lookup(egress.value, "self", null) + cidr_blocks = lookup(egress.value, "cidr_blocks", null) + ipv6_cidr_blocks = lookup(egress.value, "ipv6_cidr_blocks", null) + } + } +} + +# Create Internet Gateway +resource "aws_internet_gateway" "internet_gateway" { + depends_on = [ + aws_vpc.vpc + ] + tags = local.tags + vpc_id = aws_vpc.vpc.id +} + +# Create Route +resource "aws_route" "route" { + depends_on = [ + aws_vpc.vpc, + aws_internet_gateway.internet_gateway + ] + destination_cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.internet_gateway.id + route_table_id = aws_vpc.vpc.main_route_table_id +} + +# Create Subnet +resource "aws_subnet" "subnet" { + depends_on = [ + aws_vpc.vpc + ] + assign_ipv6_address_on_creation = var.subnet_assign_ipv6_address_on_creation + availability_zone = var.subnet_availability_zone + cidr_block = aws_vpc.vpc.cidr_block + ipv6_cidr_block = cidrsubnet(aws_vpc.vpc.ipv6_cidr_block, 8, 1) + map_public_ip_on_launch = var.subnet_map_public_ip_on_launch + tags = local.tags + vpc_id = aws_vpc.vpc.id +} diff --git a/fdio.infra.terraform/terraform-aws-vpc/outputs.tf b/fdio.infra.terraform/terraform-aws-vpc/outputs.tf new file mode 100644 index 0000000000..b58963917b --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/outputs.tf @@ -0,0 +1,24 @@ +output "vpc_id" { + value = aws_vpc.vpc.id + description = "The ID of the VPC." +} + +output "vpc_ipv6_cidr_block" { + value = aws_vpc.vpc.ipv6_cidr_block + description = "IPv6 CIDR block." +} + +output "vpc_main_route_table_id" { + value = aws_vpc.vpc.main_route_table_id + description = "The ID of the Main Route Table." +} + +output "vpc_subnet_id" { + value = aws_subnet.subnet.id + description = "The ID of the Subnet." +} + +output "vpc_security_group_id" { + value = aws_security_group.security_group.id + description = "The ID of the Security Group." +} diff --git a/fdio.infra.terraform/terraform-aws-vpc/variables.tf b/fdio.infra.terraform/terraform-aws-vpc/variables.tf new file mode 100644 index 0000000000..a501356063 --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/variables.tf @@ -0,0 +1,108 @@ +variable "tags_name" { + description = "Name used for tag." + type = string + default = "" +} + +variable "tags_environment" { + description = "Environment used for tag." + type = string + default = "" +} + +# Variables for elastic beanstalk VPC +variable "vpc_assign_generated_ipv6_cidr_block" { + description = "Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC." + type = bool + default = true +} + +variable "vpc_cidr_block" { + description = "The CIDR block for the association." + type = string + default = "192.168.0.0/24" +} + +variable "vpc_enable_dns_hostnames" { + description = "Whether or not the VPC has DNS hostname support." + type = bool + default = true +} + +variable "vpc_enable_dns_support" { + description = "Whether or not the VPC has DNS support." + type = bool + default = true +} + +variable "vpc_instance_tenancy" { + description = "The allowed tenancy of instances launched into the selected VPC." + type = string + default = "default" +} + +# Variables for Security Group +variable "security_group_description" { + description = "Security group description." + type = string + default = "Allow inbound/outbound traffic" +} + +variable "security_group_name" { + description = "Name of the security group." + type = string +} + +variable "security_group_revoke_rules_on_delete" { + description = "Instruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itself." + type = bool + default = false +} + +variable "security_group_ingress" { + description = "Ingress security group map." + type = list(any) + default = [ + { + from_port = 22 + to_port = 22 + protocol = "tcp" + self = false + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + }, + ] +} + +variable "security_group_egress" { + description = "Egress security group map." + type = list(any) + default = [ + { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + }, + ] +} + +# Variables for elastic beanstalk Subnet +variable "subnet_assign_ipv6_address_on_creation" { + description = "Specify true to indicate that network interfaces created in the specified subnet should be assigned an IPv6 address." + type = bool + default = false +} + +variable "subnet_availability_zone" { + description = "AWS availability zone" + type = string + default = "us-east-1a" +} + +variable "subnet_map_public_ip_on_launch" { + description = "Specify true to indicate that instances launched into the subnet should be assigned a public IP address." + type = bool + default = false +} diff --git a/fdio.infra.terraform/terraform-aws-vpc/versions.tf b/fdio.infra.terraform/terraform-aws-vpc/versions.tf new file mode 100644 index 0000000000..7afde83d1b --- /dev/null +++ b/fdio.infra.terraform/terraform-aws-vpc/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.1.0" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-alertmanager/README.md b/fdio.infra.terraform/terraform-nomad-alertmanager/README.md new file mode 100644 index 0000000000..f5b1f859de --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-alertmanager/README.md @@ -0,0 +1,57 @@ +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.4 | +| <a name="requirement_nomad"></a> [nomad](#requirement\_nomad) | >= 1.4.16 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_nomad"></a> [nomad](#provider\_nomad) | >= 1.4.16 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [nomad_job.nomad_job_alertmanager](https://registry.terraform.io/providers/hashicorp/nomad/latest/docs/resources/job) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_am_version"></a> [am\_version](#input\_am\_version) | Alertmanager version | `string` | `"0.21.0"` | no | +| <a name="input_auto_promote"></a> [auto\_promote](#input\_auto\_promote) | Specifies if the job should auto-promote to the canary version | `bool` | `true` | no | +| <a name="input_auto_revert"></a> [auto\_revert](#input\_auto\_revert) | Specifies if the job should auto-revert to the last stable job | `bool` | `true` | no | +| <a name="input_canary"></a> [canary](#input\_canary) | Equal to the count of the task group allows blue/green depl. | `number` | `1` | no | +| <a name="input_cpu"></a> [cpu](#input\_cpu) | CPU allocation | `number` | `1000` | no | +| <a name="input_datacenters"></a> [datacenters](#input\_datacenters) | Specifies the list of DCs to be considered placing this task | `list(string)` | <pre>[<br> "dc1"<br>]</pre> | no | +| <a name="input_group_count"></a> [group\_count](#input\_group\_count) | Specifies the number of the task groups running under this one | `number` | `1` | no | +| <a name="input_job_name"></a> [job\_name](#input\_job\_name) | Specifies a name for the job | `string` | `"alertmanager"` | no | +| <a name="input_max_parallel"></a> [max\_parallel](#input\_max\_parallel) | Specifies the maximum number of updates to perform in parallel | `number` | `1` | no | +| <a name="input_memory"></a> [memory](#input\_memory) | Specifies the memory required in MB | `number` | `1024` | no | +| <a name="input_port"></a> [port](#input\_port) | Specifies the static TCP/UDP port to allocate | `number` | `9093` | no | +| <a name="input_region"></a> [region](#input\_region) | Specifies the list of DCs to be considered placing this task | `string` | `"global"` | no | +| <a name="input_service_name"></a> [service\_name](#input\_service\_name) | Specifies the name this service will be advertised in Consul | `string` | `"alertmanager"` | no | +| <a name="input_slack_default_api_key"></a> [slack\_default\_api\_key](#input\_slack\_default\_api\_key) | Alertmanager default slack API key | `string` | `"XXXXXXXXX/XXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"` | no | +| <a name="input_slack_default_channel"></a> [slack\_default\_channel](#input\_slack\_default\_channel) | Alertmanager default slack channel | `string` | `"default-channel"` | no | +| <a name="input_slack_default_receiver"></a> [slack\_default\_receiver](#input\_slack\_default\_receiver) | Alertmanager default slack receiver | `string` | `"default-slack-receiver"` | no | +| <a name="input_slack_jenkins_api_key"></a> [slack\_jenkins\_api\_key](#input\_slack\_jenkins\_api\_key) | Alertmanager jenkins slack API key | `string` | `"XXXXXXXXX/XXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"` | no | +| <a name="input_slack_jenkins_channel"></a> [slack\_jenkins\_channel](#input\_slack\_jenkins\_channel) | Alertmanager jenkins slack channel | `string` | `"jenkins-channel"` | no | +| <a name="input_slack_jenkins_receiver"></a> [slack\_jenkins\_receiver](#input\_slack\_jenkins\_receiver) | Alertmanager jenkins slack receiver | `string` | `"jenkins-slack-receiver"` | no | +| <a name="input_use_canary"></a> [use\_canary](#input\_use\_canary) | Uses canary deployment | `bool` | `true` | no | +| <a name="input_use_host_volume"></a> [use\_host\_volume](#input\_use\_host\_volume) | Use Nomad host volume feature | `bool` | `false` | no | +| <a name="input_vault_secret"></a> [vault\_secret](#input\_vault\_secret) | Set of properties to be able to fetch secret from vault. | <pre>object({<br> use_vault_provider = bool,<br> vault_kv_policy_name = string,<br> vault_kv_path = string,<br> vault_kv_field_access_key = string,<br> vault_kv_field_secret_key = string<br> })</pre> | <pre>{<br> "use_vault_provider": false,<br> "vault_kv_field_access_key": "access_key",<br> "vault_kv_field_secret_key": "secret_key",<br> "vault_kv_path": "secret/data/alertmanager",<br> "vault_kv_policy_name": "kv"<br>}</pre> | no | +| <a name="input_volume_destination"></a> [volume\_destination](#input\_volume\_destination) | Specifies where the volume should be mounted inside the task | `string` | `"/data/"` | no | +| <a name="input_volume_source"></a> [volume\_source](#input\_volume\_source) | The name of the volume to request | `string` | `"persistence"` | no | + +## Outputs + +No outputs. +<!-- END_TF_DOCS -->
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-alertmanager/conf/nomad/alertmanager.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-alertmanager/conf/nomad/alertmanager.hcl.tftpl new file mode 100644 index 0000000000..87206ac5a0 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-alertmanager/conf/nomad/alertmanager.hcl.tftpl @@ -0,0 +1,377 @@ +job "${job_name}" { + # The "region" parameter specifies the region in which to execute the job. + # If omitted, this inherits the default region name of "global". + # region = "${region}" + + # The "datacenters" parameter specifies the list of datacenters which should + # be considered when placing this task. This must be provided. + datacenters = "${datacenters}" + + # The "type" parameter controls the type of job, which impacts the scheduler's + # decision on placement. This configuration is optional and defaults to + # "service". For a full list of job types and their differences, please see + # the online documentation. + # + # https://www.nomadproject.io/docs/jobspec/schedulers + # + type = "service" + + update { + # The "max_parallel" parameter specifies the maximum number of updates to + # perform in parallel. In this case, this specifies to update a single task + # at a time. + max_parallel = ${max_parallel} + + health_check = "checks" + + # The "min_healthy_time" parameter specifies the minimum time the allocation + # must be in the healthy state before it is marked as healthy and unblocks + # further allocations from being updated. + min_healthy_time = "10s" + + # The "healthy_deadline" parameter specifies the deadline in which the + # allocation must be marked as healthy after which the allocation is + # automatically transitioned to unhealthy. Transitioning to unhealthy will + # fail the deployment and potentially roll back the job if "auto_revert" is + # set to true. + healthy_deadline = "3m" + + # The "progress_deadline" parameter specifies the deadline in which an + # allocation must be marked as healthy. The deadline begins when the first + # allocation for the deployment is created and is reset whenever an allocation + # as part of the deployment transitions to a healthy state. If no allocation + # transitions to the healthy state before the progress deadline, the + # deployment is marked as failed. + progress_deadline = "10m" + +%{ if use_canary } + # The "canary" parameter specifies that changes to the job that would result + # in destructive updates should create the specified number of canaries + # without stopping any previous allocations. Once the operator determines the + # canaries are healthy, they can be promoted which unblocks a rolling update + # of the remaining allocations at a rate of "max_parallel". + # + # Further, setting "canary" equal to the count of the task group allows + # blue/green deployments. When the job is updated, a full set of the new + # version is deployed and upon promotion the old version is stopped. + canary = ${canary} + + # Specifies if the job should auto-promote to the canary version when all + # canaries become healthy during a deployment. Defaults to false which means + # canaries must be manually updated with the nomad deployment promote + # command. + auto_promote = ${auto_promote} + + # The "auto_revert" parameter specifies if the job should auto-revert to the + # last stable job on deployment failure. A job is marked as stable if all the + # allocations as part of its deployment were marked healthy. + auto_revert = ${auto_revert} +%{ endif } + } + + # All groups in this job should be scheduled on different hosts. + constraint { + operator = "distinct_hosts" + value = "true" + } + + # The "group" stanza defines a series of tasks that should be co-located on + # the same Nomad client. Any task within a group will be placed on the same + # client. + # + # https://www.nomadproject.io/docs/job-specification/group + # + group "${job_name}-group-1" { + # The "count" parameter specifies the number of the task groups that should + # be running under this group. This value must be non-negative and defaults + # to 1. + count = ${group_count} + + # The volume stanza allows the group to specify that it requires a given + # volume from the cluster. The key of the stanza is the name of the volume + # as it will be exposed to task configuration. + # + # https://www.nomadproject.io/docs/job-specification/volume + %{ if use_host_volume } + volume "${job_name}-volume-1" { + type = "host" + read_only = false + source = "${volume_source}" + } + %{ endif } + + # The restart stanza configures a tasks's behavior on task failure. Restarts + # happen on the client that is running the task. + # + # https://www.nomadproject.io/docs/job-specification/restart + # + restart { + interval = "30m" + attempts = 40 + delay = "15s" + mode = "delay" + } + + # The constraint allows restricting the set of eligible nodes. Constraints + # may filter on attributes or client metadata. + # + # https://www.nomadproject.io/docs/job-specification/constraint + # + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + + constraint { + attribute = "$${node.class}" + value = "builder" + } + + # The network stanza specifies the networking requirements for the task + # group, including the network mode and port allocations. When scheduling + # jobs in Nomad they are provisioned across your fleet of machines along + # with other jobs and services. Because you don't know in advance what host + # your job will be provisioned on, Nomad will provide your tasks with + # network configuration when they start up. + # + # https://www.nomadproject.io/docs/job-specification/network + # + network { + port "${service_name}" { + static = ${port} + to = ${port} + } + } + + # The "task" stanza creates an individual unit of work, such as a Docker + # container, web application, or batch processing. + # + # https://www.nomadproject.io/docs/job-specification/task + # + task "${job_name}-task-1" { + # The "driver" parameter specifies the task driver that should be used to + # run the task. + driver = "exec" + + %{ if use_host_volume } + volume_mount { + volume = "${job_name}-volume-1" + destination = "${volume_destination}" + read_only = false + } + %{ endif } + + %{ if use_vault_provider } + vault { + policies = "${vault_kv_policy_name}" + } + %{ endif } + + # The "config" stanza specifies the driver configuration, which is passed + # directly to the driver to start the task. The details of configurations + # are specific to each driver, so please see specific driver + # documentation for more information. + config { + command = "local/alertmanager-${version}.linux-amd64/alertmanager" + args = [ + "--config.file=secrets/alertmanager.yml" + ] + } + + # The artifact stanza instructs Nomad to fetch and unpack a remote resource, + # such as a file, tarball, or binary. Nomad downloads artifacts using the + # popular go-getter library, which permits downloading artifacts from a + # variety of locations using a URL as the input source. + # + # https://www.nomadproject.io/docs/job-specification/artifact + # + artifact { + source = "${url}" + } + + # The "template" stanza instructs Nomad to manage a template, such as + # a configuration file or script. This template can optionally pull data + # from Consul or Vault to populate runtime configuration data. + # + # https://www.nomadproject.io/docs/job-specification/template + # + template { + change_mode = "noop" + change_signal = "SIGINT" + destination = "secrets/alertmanager.yml" + left_delimiter = "{{{" + right_delimiter = "}}}" + data = <<EOH +# The directory from which notification templates are read. +templates: +- '/etc/alertmanager/template/*.tmpl' + +#tls_config: +# # CA certificate to validate the server certificate with. +# ca_file: <filepath> ] +# +# # Certificate and key files for client cert authentication to the server. +# cert_file: <filepath> +# key_file: <filepath> +# +# # ServerName extension to indicate the name of the server. +# # http://tools.ietf.org/html/rfc4366#section-3.1 +# server_name: <string> +# +# # Disable validation of the server certificate. +# insecure_skip_verify: true + +# The root route on which each incoming alert enters. +route: + receiver: '${slack_default_receiver}' + + # The labels by which incoming alerts are grouped together. For example, + # multiple alerts coming in for cluster=A and alertname=LatencyHigh would + # be batched into a single group. + # + # To aggregate by all possible labels use '...' as the sole label name. + # This effectively disables aggregation entirely, passing through all + # alerts as-is. This is unlikely to be what you want, unless you have + # a very low alert volume or your upstream notification system performs + # its own grouping. Example: group_by: [...] + group_by: ['alertname'] + + # When a new group of alerts is created by an incoming alert, wait at + # least 'group_wait' to send the initial notification. + # This way ensures that you get multiple alerts for the same group that start + # firing shortly after another are batched together on the first + # notification. + group_wait: 30s + + # When the first notification was sent, wait 'group_interval' to send a batch + # of new alerts that started firing for that group. + group_interval: 5m + + # If an alert has successfully been sent, wait 'repeat_interval' to + # resend them. + repeat_interval: 3h + + # All the above attributes are inherited by all child routes and can + # overwritten on each. + # The child route trees. + routes: + - match_re: + alertname: JenkinsJob.* + receiver: ${slack_jenkins_receiver} + routes: + - match: + severity: critical + receiver: '${slack_jenkins_receiver}' + + - match_re: + service: .* + receiver: ${slack_default_receiver} + routes: + - match: + severity: critical + receiver: '${slack_default_receiver}' + +# Inhibition rules allow to mute a set of alerts given that another alert is +# firing. +# We use this to mute any warning-level notifications if the same alert is +# already critical. +inhibit_rules: +- source_match: + severity: 'critical' + target_match: + severity: 'warning' + equal: ['alertname', 'instance'] + +receivers: +- name: '${slack_jenkins_receiver}' + slack_configs: + - api_url: 'https://hooks.slack.com/services/${slack_jenkins_api_key}' + channel: '#${slack_jenkins_channel}' + send_resolved: true + icon_url: https://avatars3.githubusercontent.com/u/3380462 + title: |- + [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }} + {{- if gt (len .CommonLabels) (len .GroupLabels) -}} + {{" "}}( + {{- with .CommonLabels.Remove .GroupLabels.Names }} + {{- range $index, $label := .SortedPairs -}} + {{ if $index }}, {{ end }} + {{- $label.Name }}="{{ $label.Value -}}" + {{- end }} + {{- end -}} + ) + {{- end }} + text: >- + {{ range .Alerts -}} + *Alert:* {{ .Annotations.summary }}{{ if .Labels.severity }} - `{{ .Labels.severity }}`{{ end }} + + *Description:* {{ .Annotations.description }} + + *Details:* + {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}` + {{ end }} + {{ end }} + +- name: '${slack_default_receiver}' + slack_configs: + - api_url: 'https://hooks.slack.com/services/${slack_default_api_key}' + channel: '#${slack_default_channel}' + send_resolved: true + icon_url: https://avatars3.githubusercontent.com/u/3380462 + title: |- + [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }} + {{- if gt (len .CommonLabels) (len .GroupLabels) -}} + {{" "}}( + {{- with .CommonLabels.Remove .GroupLabels.Names }} + {{- range $index, $label := .SortedPairs -}} + {{ if $index }}, {{ end }} + {{- $label.Name }}="{{ $label.Value -}}" + {{- end }} + {{- end -}} + ) + {{- end }} + text: >- + {{ range .Alerts -}} + *Alert:* {{ .Annotations.summary }}{{ if .Labels.severity }} - `{{ .Labels.severity }}`{{ end }} + + *Description:* {{ .Annotations.description }} + + *Details:* + {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}` + {{ end }} + {{ end }} +EOH + } + + # The service stanza instructs Nomad to register a service with Consul. + # + # https://www.nomadproject.io/docs/job-specification/service + # + service { + name = "${service_name}" + port = "${service_name}" + tags = [ "${service_name}$${NOMAD_ALLOC_INDEX}" ] + check { + name = "Alertmanager Check Live" + type = "http" + path = "/-/healthy" + interval = "10s" + timeout = "2s" + } + } + + # The "resources" stanza describes the requirements a task needs to + # execute. Resource requirements include memory, network, cpu, and more. + # This ensures the task will execute on a machine that contains enough + # resource capacity. + # + # https://www.nomadproject.io/docs/job-specification/resources + # + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/main.tf b/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/main.tf new file mode 100644 index 0000000000..745e450a8c --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/main.tf @@ -0,0 +1,14 @@ +module "alertmanager" { + providers = { + nomad = nomad.yul1 + } + source = "../" + + # alertmanager + datacenters = ["yul1"] + slack_jenkins_api_key = "TE07RD1V1/B01U1NV9HV3/hKZXJJ74g2JcISq4K3QC1eG9" + slack_jenkins_channel = "fdio-jobs-monitoring" + slack_default_api_key = "TE07RD1V1/B01UUK23B6C/hZTcCu42FUv8d6rtirHtcYIi" + slack_default_channel = "fdio-infra-monitoring" + am_version = "0.23.0" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/providers.tf b/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/providers.tf new file mode 100644 index 0000000000..42a6a45ce0 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/providers.tf @@ -0,0 +1,13 @@ +provider "nomad" { + address = var.nomad_provider_address + alias = "yul1" + # ca_file = var.nomad_provider_ca_file + # cert_file = var.nomad_provider_cert_file + # key_file = var.nomad_provider_key_file +} + +provider "vault" { + address = var.vault_provider_address + skip_tls_verify = var.vault_provider_skip_tls_verify + token = var.vault_provider_token +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/variables.tf b/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/variables.tf new file mode 100644 index 0000000000..569ba29c87 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/variables.tf @@ -0,0 +1,47 @@ +variable "nomad_acl" { + description = "Nomad ACLs enabled/disabled." + type = bool + default = false +} + +variable "nomad_provider_address" { + description = "FD.io Nomad cluster address." + type = string + default = "http://10.30.51.23:4646" +} + +variable "nomad_provider_ca_file" { + description = "A local file path to a PEM-encoded certificate authority." + type = string + default = "/etc/nomad.d/ssl/nomad-ca.pem" +} + +variable "nomad_provider_cert_file" { + description = "A local file path to a PEM-encoded certificate." + type = string + default = "/etc/nomad.d/ssl/nomad-cli.pem" +} + +variable "nomad_provider_key_file" { + description = "A local file path to a PEM-encoded private key." + type = string + default = "/etc/nomad.d/ssl/nomad-cli-key.pem" +} + +variable "vault_provider_address" { + description = "Vault cluster address." + type = string + default = "http://10.30.51.23:8200" +} + +variable "vault_provider_skip_tls_verify" { + description = "Verification of the Vault server's TLS certificate." + type = bool + default = false +} + +variable "vault_provider_token" { + description = "Vault root token." + type = string + sensitive = true +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/versions.tf b/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/versions.tf new file mode 100644 index 0000000000..0cabc3c6e5 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-alertmanager/fdio/versions.tf @@ -0,0 +1,17 @@ +terraform { + backend "consul" { + address = "consul.service.consul:8500" + scheme = "http" + path = "terraform/alertmanager" + } + required_providers { + nomad = { + source = "hashicorp/nomad" + version = ">= 1.4.16" + } + vault = { + version = ">= 3.2.1" + } + } + required_version = ">= 1.1.4" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-alertmanager/main.tf b/fdio.infra.terraform/terraform-nomad-alertmanager/main.tf new file mode 100644 index 0000000000..e8a1389150 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-alertmanager/main.tf @@ -0,0 +1,48 @@ +locals { + datacenters = join(",", var.datacenters) + url = join("", + [ + "https://github.com", + "/prometheus/alertmanager/releases/download/", + "v${var.am_version}/", + "alertmanager-${var.am_version}.linux-amd64.tar.gz" + ] + ) +} + +resource "nomad_job" "nomad_job_alertmanager" { + jobspec = templatefile( + "${path.module}/conf/nomad/alertmanager.hcl.tftpl", + { + auto_promote = var.auto_promote, + auto_revert = var.auto_revert, + canary = var.canary, + cpu = var.cpu, + datacenters = local.datacenters, + group_count = var.group_count, + job_name = var.job_name, + max_parallel = var.max_parallel, + memory = var.memory + port = var.port, + region = var.region, + service_name = var.service_name, + slack_jenkins_api_key = var.slack_jenkins_api_key, + slack_jenkins_channel = var.slack_jenkins_channel, + slack_jenkins_receiver = var.slack_jenkins_receiver, + slack_default_api_key = var.slack_default_api_key, + slack_default_channel = var.slack_default_channel, + slack_default_receiver = var.slack_default_receiver, + url = local.url, + use_canary = var.use_canary, + use_host_volume = var.use_host_volume, + use_vault_provider = var.vault_secret.use_vault_provider, + vault_kv_policy_name = var.vault_secret.vault_kv_policy_name, + vault_kv_path = var.vault_secret.vault_kv_path, + vault_kv_field_access_key = var.vault_secret.vault_kv_field_access_key, + vault_kv_field_secret_key = var.vault_secret.vault_kv_field_secret_key, + version = var.am_version, + volume_destination = var.volume_destination, + volume_source = var.volume_source + }) + detach = false +} diff --git a/fdio.infra.terraform/terraform-nomad-alertmanager/variables.tf b/fdio.infra.terraform/terraform-nomad-alertmanager/variables.tf new file mode 100644 index 0000000000..e452598fa6 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-alertmanager/variables.tf @@ -0,0 +1,157 @@ +# Nomad +variable "datacenters" { + description = "Specifies the list of DCs to be considered placing this task" + type = list(string) + default = ["dc1"] +} + +variable "region" { + description = "Specifies the list of DCs to be considered placing this task" + type = string + default = "global" +} + +variable "volume_source" { + description = "The name of the volume to request" + type = string + default = "persistence" +} + +# Alertmanager +variable "am_version" { + description = "Alertmanager version" + type = string + default = "0.21.0" +} + +variable "auto_promote" { + description = "Specifies if the job should auto-promote to the canary version" + type = bool + default = true +} + +variable "auto_revert" { + description = "Specifies if the job should auto-revert to the last stable job" + type = bool + default = true +} + +variable "canary" { + description = "Equal to the count of the task group allows blue/green depl." + type = number + default = 1 +} + +variable "cpu" { + description = "CPU allocation" + type = number + default = 1000 +} + +variable "group_count" { + description = "Specifies the number of the task groups running under this one" + type = number + default = 1 +} + +variable "job_name" { + description = "Specifies a name for the job" + type = string + default = "alertmanager" +} + +variable "max_parallel" { + description = "Specifies the maximum number of updates to perform in parallel" + type = number + default = 1 +} + +variable "memory" { + description = "Specifies the memory required in MB" + type = number + default = 1024 +} + +variable "port" { + description = "Specifies the static TCP/UDP port to allocate" + type = number + default = 9093 +} + +variable "service_name" { + description = "Specifies the name this service will be advertised in Consul" + type = string + default = "alertmanager" +} + +variable "use_canary" { + description = "Uses canary deployment" + type = bool + default = true +} + +variable "use_host_volume" { + description = "Use Nomad host volume feature" + type = bool + default = false +} + +variable "vault_secret" { + type = object({ + use_vault_provider = bool, + vault_kv_policy_name = string, + vault_kv_path = string, + vault_kv_field_access_key = string, + vault_kv_field_secret_key = string + }) + description = "Set of properties to be able to fetch secret from vault." + default = { + use_vault_provider = false + vault_kv_policy_name = "kv" + vault_kv_path = "secret/data/alertmanager" + vault_kv_field_access_key = "access_key" + vault_kv_field_secret_key = "secret_key" + } +} + +variable "volume_destination" { + description = "Specifies where the volume should be mounted inside the task" + type = string + default = "/data/" +} + +variable "slack_jenkins_api_key" { + description = "Alertmanager jenkins slack API key" + type = string + default = "XXXXXXXXX/XXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX" +} + +variable "slack_jenkins_receiver" { + description = "Alertmanager jenkins slack receiver" + type = string + default = "jenkins-slack-receiver" +} + +variable "slack_jenkins_channel" { + description = "Alertmanager jenkins slack channel" + type = string + default = "jenkins-channel" +} + +variable "slack_default_api_key" { + description = "Alertmanager default slack API key" + type = string + default = "XXXXXXXXX/XXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX" +} + +variable "slack_default_receiver" { + description = "Alertmanager default slack receiver" + type = string + default = "default-slack-receiver" +} + +variable "slack_default_channel" { + description = "Alertmanager default slack channel" + type = string + default = "default-channel" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-alertmanager/versions.tf b/fdio.infra.terraform/terraform-nomad-alertmanager/versions.tf new file mode 100644 index 0000000000..5f283ed4ea --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-alertmanager/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + nomad = { + source = "hashicorp/nomad" + version = ">= 1.4.16" + } + } + required_version = ">= 1.1.4" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-prometheus/README.md b/fdio.infra.terraform/terraform-nomad-prometheus/README.md new file mode 100644 index 0000000000..e0568c376c --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-prometheus/README.md @@ -0,0 +1,52 @@ +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.4 | +| <a name="requirement_nomad"></a> [nomad](#requirement\_nomad) | >= 1.4.16 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_nomad"></a> [nomad](#provider\_nomad) | >= 1.4.16 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [nomad_job.nomad_job_prometheus](https://registry.terraform.io/providers/hashicorp/nomad/latest/docs/resources/job) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_auto_promote"></a> [auto\_promote](#input\_auto\_promote) | Specifies if the job should auto-promote to the canary version | `bool` | `true` | no | +| <a name="input_auto_revert"></a> [auto\_revert](#input\_auto\_revert) | Specifies if the job should auto-revert to the last stable job | `bool` | `true` | no | +| <a name="input_canary"></a> [canary](#input\_canary) | Equal to the count of the task group allows blue/green depl. | `number` | `1` | no | +| <a name="input_cpu"></a> [cpu](#input\_cpu) | CPU allocation | `number` | `2000` | no | +| <a name="input_data_dir"></a> [data\_dir](#input\_data\_dir) | Prometheus DISK allocation | `string` | `"/data"` | no | +| <a name="input_datacenters"></a> [datacenters](#input\_datacenters) | Specifies the list of DCs to be considered placing this task | `list(string)` | <pre>[<br> "dc1"<br>]</pre> | no | +| <a name="input_group_count"></a> [group\_count](#input\_group\_count) | Specifies the number of the task groups running under this one | `number` | `4` | no | +| <a name="input_job_name"></a> [job\_name](#input\_job\_name) | Specifies a name for the job | `string` | `"prometheus"` | no | +| <a name="input_max_parallel"></a> [max\_parallel](#input\_max\_parallel) | Specifies the maximum number of updates to perform in parallel | `number` | `1` | no | +| <a name="input_memory"></a> [memory](#input\_memory) | Specifies the memory required in MB | `number` | `4096` | no | +| <a name="input_pm_version"></a> [pm\_version](#input\_pm\_version) | Prometheus version | `string` | `"2.33.1"` | no | +| <a name="input_port"></a> [port](#input\_port) | Specifies the static TCP/UDP port to allocate | `number` | `9090` | no | +| <a name="input_region"></a> [region](#input\_region) | Specifies the list of DCs to be considered placing this task | `string` | `"global"` | no | +| <a name="input_service_name"></a> [service\_name](#input\_service\_name) | Specifies the name this service will be advertised in Consul | `string` | `"prometheus"` | no | +| <a name="input_use_canary"></a> [use\_canary](#input\_use\_canary) | Uses canary deployment | `bool` | `true` | no | +| <a name="input_use_host_volume"></a> [use\_host\_volume](#input\_use\_host\_volume) | Use Nomad host volume feature | `bool` | `true` | no | +| <a name="input_vault_secret"></a> [vault\_secret](#input\_vault\_secret) | Set of properties to be able to fetch secret from vault. | <pre>object({<br> use_vault_provider = bool,<br> vault_kv_policy_name = string,<br> vault_kv_path = string,<br> vault_kv_field_access_key = string,<br> vault_kv_field_secret_key = string<br> })</pre> | <pre>{<br> "use_vault_provider": false,<br> "vault_kv_field_access_key": "access_key",<br> "vault_kv_field_secret_key": "secret_key",<br> "vault_kv_path": "secret/data/prometheus",<br> "vault_kv_policy_name": "kv"<br>}</pre> | no | +| <a name="input_volume_destination"></a> [volume\_destination](#input\_volume\_destination) | Specifies where the volume should be mounted inside the task | `string` | `"/data/"` | no | +| <a name="input_volume_source"></a> [volume\_source](#input\_volume\_source) | The name of the volume to request | `string` | `"prod-volume-data1-1"` | no | + +## Outputs + +No outputs. +<!-- END_TF_DOCS -->
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-prometheus/conf/nomad/prometheus.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-prometheus/conf/nomad/prometheus.hcl.tftpl new file mode 100644 index 0000000000..4eb4428988 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-prometheus/conf/nomad/prometheus.hcl.tftpl @@ -0,0 +1,676 @@ +job "${job_name}" { + # The "region" parameter specifies the region in which to execute the job. + # If omitted, this inherits the default region name of "global". + # region = "${region}" + + # The "datacenters" parameter specifies the list of datacenters which should + # be considered when placing this task. This must be provided. + datacenters = "${datacenters}" + + # The "type" parameter controls the type of job, which impacts the scheduler's + # decision on placement. + # + # https://www.nomadproject.io/docs/jobspec/schedulers + # + type = "service" + + update { + # The "max_parallel" parameter specifies the maximum number of updates to + # perform in parallel. + max_parallel = ${max_parallel} + + health_check = "checks" + + # The "min_healthy_time" parameter specifies the minimum time the allocation + # must be in the healthy state before it is marked as healthy and unblocks + # further allocations from being updated. + min_healthy_time = "10s" + + # The "healthy_deadline" parameter specifies the deadline in which the + # allocation must be marked as healthy after which the allocation is + # automatically transitioned to unhealthy. Transitioning to unhealthy will + # fail the deployment and potentially roll back the job if "auto_revert" is + # set to true. + healthy_deadline = "3m" + + # The "progress_deadline" parameter specifies the deadline in which an + # allocation must be marked as healthy. The deadline begins when the first + # allocation for the deployment is created and is reset whenever an allocation + # as part of the deployment transitions to a healthy state. If no allocation + # transitions to the healthy state before the progress deadline, the + # deployment is marked as failed. + progress_deadline = "10m" + +%{ if use_canary } + # The "canary" parameter specifies that changes to the job that would result + # in destructive updates should create the specified number of canaries + # without stopping any previous allocations. Once the operator determines the + # canaries are healthy, they can be promoted which unblocks a rolling update + # of the remaining allocations at a rate of "max_parallel". + # + # Further, setting "canary" equal to the count of the task group allows + # blue/green deployments. When the job is updated, a full set of the new + # version is deployed and upon promotion the old version is stopped. + canary = ${canary} + + # Specifies if the job should auto-promote to the canary version when all + # canaries become healthy during a deployment. Defaults to false which means + # canaries must be manually updated with the nomad deployment promote + # command. + auto_promote = ${auto_promote} + + # The "auto_revert" parameter specifies if the job should auto-revert to the + # last stable job on deployment failure. A job is marked as stable if all the + # allocations as part of its deployment were marked healthy. + auto_revert = ${auto_revert} +%{ endif } + } + + # The "group" stanza defines a series of tasks that should be co-located on + # the same Nomad client. Any task within a group will be placed on the same + # client. + # + # https://www.nomadproject.io/docs/job-specification/group + # + group "${job_name}-group-1" { + # The "count" parameter specifies the number of the task groups that should + # be running under this group. This value must be non-negative. + count = ${group_count} + + # The volume stanza allows the group to specify that it requires a given + # volume from the cluster. The key of the stanza is the name of the volume + # as it will be exposed to task configuration. + # + # https://www.nomadproject.io/docs/job-specification/volume + # + %{ if use_host_volume } + volume "${job_name}-volume-1" { + type = "host" + read_only = false + source = "${volume_source}" + } + %{ endif } + + # The restart stanza configures a tasks's behavior on task failure. Restarts + # happen on the client that is running the task. + # + # https://www.nomadproject.io/docs/job-specification/restart + # + restart { + interval = "30m" + attempts = 40 + delay = "15s" + mode = "delay" + } + + # The constraint allows restricting the set of eligible nodes. Constraints + # may filter on attributes or client metadata. + # + # https://www.nomadproject.io/docs/job-specification/constraint + # + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + + # The network stanza specifies the networking requirements for the task + # group, including the network mode and port allocations. When scheduling + # jobs in Nomad they are provisioned across your fleet of machines along + # with other jobs and services. Because you don't know in advance what host + # your job will be provisioned on, Nomad will provide your tasks with + # network configuration when they start up. + # + # https://www.nomadproject.io/docs/job-specification/network + # + network { + port "${service_name}" { + static = ${port} + to = ${port} + } + } + + # The "task" stanza creates an individual unit of work, such as a Docker + # container, web application, or batch processing. + # + # https://www.nomadproject.io/docs/job-specification/task + # + task "${job_name}-task-1" { + # The "driver" parameter specifies the task driver that should be used to + # run the task. + driver = "exec" + + %{ if use_host_volume } + volume_mount { + volume = "${job_name}-volume-1" + destination = "${volume_destination}" + read_only = false + } + %{ endif } + + %{ if use_vault_provider } + vault { + policies = "${vault_kv_policy_name}" + } + %{ endif } + + # The "config" stanza specifies the driver configuration, which is passed + # directly to the driver to start the task. The details of configurations + # are specific to each driver, so please see specific driver + # documentation for more information. + config { + command = "local/prometheus-${version}.linux-amd64/prometheus" + args = [ + "--config.file=secrets/prometheus.yml", + "--web.config.file=secrets/web-config.yml", + "--storage.tsdb.path=${volume_destination}prometheus/", + "--storage.tsdb.retention.time=7d" + ] + } + + # The artifact stanza instructs Nomad to fetch and unpack a remote + # resource, such as a file, tarball, or binary. Nomad downloads artifacts + # using the popular go-getter library, which permits downloading artifacts + # from a variety of locations using a URL as the input source. + # + # https://www.nomadproject.io/docs/job-specification/artifact + # + artifact { + source = "${artifact_source}" + options { + checksum = "sha256:${artifact_source_checksum}" + } + } + + # The "template" stanza instructs Nomad to manage a template, such as + # a configuration file or script. This template can optionally pull data + # from Consul or Vault to populate runtime configuration data. + # + # https://www.nomadproject.io/docs/job-specification/template + # + template { + change_mode = "noop" + change_signal = "SIGINT" + destination = "secrets/cert_file.crt" + left_delimiter = "{{{" + right_delimiter = "}}}" + data = <<EOH +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUDtmFbbnYaXbXH5ddtHi9l25wM7owDQYJKoZIhvcNAQEL +BQAwaTELMAkGA1UEBhMCU0sxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEiMCAGA1UEAwwZcHJvbWV0aGV1cy5z +ZXJ2aWNlLmNvbnN1bDAeFw0yMjEyMzEyMDMxMDFaFw0yMzAxMzAyMDMxMDFaMGkx +CzAJBgNVBAYTAlNLMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl +cm5ldCBXaWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGXByb21ldGhldXMuc2Vydmlj +ZS5jb25zdWwwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCGH4Tyj+9G +wYJNb3ubIdr5r0/DZL6XEnRIMiz88TN2QmdwAGKyQqQd7ka0IkdDHPhpRuK8IV1g +ELQhKab7YJCa6zWuy+rQ6JFlotGC+2tIXd3MDriUd1VPVoX6fw/5zUK/2j6exBk4 +iqxPXHchQLzZ0viUXhQIBS1IUMTbfc0vjA8U0uPgpmAR7ieePWFwmUDxjOLMvJw6 ++goeOfaHhW4yYgT+kg7L3rT62G+KG6Op/p7k7BNZ6G6Y6K6uJ7Z/AayAClF2sPZz +UIGr0uEDvD4IcAsfQgpR5vK/SVBFU5+DSO68mm11m+8IH/HA6GvNSEvCRC0Wtrsm +Dyq+9S3wZ7tNi7msjQWWKTB1GvTbCbPE1G/q5GJdoKUnioys6AMP4DTEV9o3lCSg +0sjYnkSTKgRplnuY/7Y2qSNnD1Rw0ZneSkF+8ocgiYcTvtyOY2fkhlT2VaQLX987 +m7892ikPvoCnc/LVeREWW7hCuIQ1E1CCqg304Kd9gCgKoOGXoYmC/3wgJW0RkaM0 +x5DpNLYx0y11CPVg315dvprOuedap6J3CNhBE3fO8ymwepFTzTcWLWgSVWrRLZnx +Lgb4SPhjxPg6cCZptkmXrPA+9SgW8iNHd/Fer6MAs82Kcp2T1C+qq9RurL/jjxTD +JaFrwZC2lgWELToMyVDrkBJJbA/2cU9CMQIDAQABo1MwUTAdBgNVHQ4EFgQUx1Mi +fylZExNnIz0EkrPRdXYmHmAwHwYDVR0jBBgwFoAUx1MifylZExNnIz0EkrPRdXYm +HmAwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAbvlpMg4YRTNe +0cgqMZky/GpNjvE/zFManUGgYns8TKyZ8U0laBxRQ4XU/fASwAcOBJYtrkG7w8z+ +FaOUptaOlNGW1VWsPDJt8ZQ2gAcTwKSW2EsBWCmOUJVNH5F0f6fTSqIUIXyxhP2w +JVniSkfarhb/Y1EDCACdr7Xpu6iF+nQo2o4/HE4Wkto4qwvlrdApYv4dl5J1TWjq +72fO9axDlNnEGVxa3C3xvKOQqWrEUy/HqC9p4it1yCiq6IYVLyve0meVFBY9xNXU +137AN7ks4ouuR1FZQkhLtqFuIekSZ5l4G4alwdv1NB8vohJMuMJyk9DarTLqXcYU +1uypZSmgREn8ByYrj4ochkSpiPw7wgK4H1Aa2cy4KUuzmLLShYu6Mov7hyJDoJSe +JsDVNoEBuhql4jENATqbWT3pIgYwBvBEXuYXqekcNmVZkKiSOlsxKFfSz21HYDgA +lCu4SMtlRYHcm4TuoTuy/FEPxHSjFY3pMciJrnO/qUrv9LlWPe1wjKhZLRPEebTk +r+Oh+aVWpy3ps7shPTjczOrmQykWWBGAjndZjZi4VvZNRxkGZuNwzzZcEkzt0Db7 +l83pTRD58mvLHWl2QXoBS3t7IM6sOMwQvPx1Inp7hb7UIpNsJQaUrhhfKqy0sK18 +mXs4VRtrxYycXxsLbk0SaZGh+juT53M= +-----END CERTIFICATE----- +EOH + } + + template { + change_mode = "noop" + change_signal = "SIGINT" + destination = "secrets/key_file.key" + left_delimiter = "{{{" + right_delimiter = "}}}" + data = <<EOH +-----BEGIN PRIVATE KEY----- +MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQCGH4Tyj+9GwYJN +b3ubIdr5r0/DZL6XEnRIMiz88TN2QmdwAGKyQqQd7ka0IkdDHPhpRuK8IV1gELQh +Kab7YJCa6zWuy+rQ6JFlotGC+2tIXd3MDriUd1VPVoX6fw/5zUK/2j6exBk4iqxP +XHchQLzZ0viUXhQIBS1IUMTbfc0vjA8U0uPgpmAR7ieePWFwmUDxjOLMvJw6+goe +OfaHhW4yYgT+kg7L3rT62G+KG6Op/p7k7BNZ6G6Y6K6uJ7Z/AayAClF2sPZzUIGr +0uEDvD4IcAsfQgpR5vK/SVBFU5+DSO68mm11m+8IH/HA6GvNSEvCRC0WtrsmDyq+ +9S3wZ7tNi7msjQWWKTB1GvTbCbPE1G/q5GJdoKUnioys6AMP4DTEV9o3lCSg0sjY +nkSTKgRplnuY/7Y2qSNnD1Rw0ZneSkF+8ocgiYcTvtyOY2fkhlT2VaQLX987m789 +2ikPvoCnc/LVeREWW7hCuIQ1E1CCqg304Kd9gCgKoOGXoYmC/3wgJW0RkaM0x5Dp +NLYx0y11CPVg315dvprOuedap6J3CNhBE3fO8ymwepFTzTcWLWgSVWrRLZnxLgb4 +SPhjxPg6cCZptkmXrPA+9SgW8iNHd/Fer6MAs82Kcp2T1C+qq9RurL/jjxTDJaFr +wZC2lgWELToMyVDrkBJJbA/2cU9CMQIDAQABAoICAA5AQByT3Z07h3BZ5ZzUqpM4 +JPYCeNvNeqyHJE+WA11P7fSxHcuKGC0T+dA/Cipf5CcvgHzz4JuJ+tHBPrxcBNFp +J5GUmjUrWPOfKrrLoxkT3DLH56Xizh45d8/ne1eUD0EaW+f7tyBSX7+o+AGBAu/0 +IjSFkIRPpIGYD2qxAcHJFHsmc08V7oRJNU1zgSx5JDTmPtz5N3Juye9vQjohG9Xf +o183Pro7xigXIjbe+/NemhyB1waJE2NM6e6YSqRRFbafIgvF/tG+3qBWrlD6ye6U +lSHznuwX6XgYvp43Je5JrBA/Kl1CPdIzrrjMGVQ9F8ui+dV9ggInv2d93q06IGUU +D1o9XsZivYkn1EkLEhFXD5CYj6oR1M+MyvUrBD0bJePQCBUo+WJ2sEDt9PN2AtFL +9j7NKK/xXX5cTdAajeIvSS1PUGAHi7r1OF/c7bn3UFNOuOBEYzLsSZGP34AVglor +NON0ENCTuylmDSFd8vpaKFQpV5SK3M2k8dPRe7VEu2C9UlRvAq0xnabSHNxbwNLU +KuGDMSCKDc2npf3oCeQKU2PngAcePnwWSiapAkf5OqltQ/vMbrEpROpfzXLlRxLZ +76MDMFMQkT7m0hik6aPBHTitcWRalxHhK0ze8GvO0wesIBdyYShPKg+VDNg3qFMm +epVXzoi8xNzW8S6yi9DJAoIBAQC2l90VF5evDsv8nwsWMIa/rFGGLitpw23+oNcZ +xsIDMsGie06GYwzYHNRsd3sqK5TNLtl2vJGaVNbeDcC5T22NAYPRjNas7I5svIki +SnT4K68ICIVVxtfETbh2qoXSu+O3pyWJmHqqcQrvW2DlUvs0nxk/v3GukFjTVbuU +qmXp1KjPAVMNYoWNCJkHLEpq6e3K3q4YhEImGhMbN8suvVR9+fkKx8QvKHcqT2kn +9AlK7t57IPqovbni9KMfMZ+wPqw6HsYTL8lQE5NaqMB5q9Pl3SnzcRR0FSadNAiD +/W9jWyMazE0UsNDn241X81tVlU78Kx9S/IN97m/FSeDA1XudAoIBAQC8CzVeHxTw +U+ts/fi1XEuWOph2cIm6qd4aiyGX/riux0O6GUFuIQkosP5StWJyNPLBohWHC6eq +hPk7b0vPWmxuhttUPLA/+6+CICC0jEMWvnDAd5aJULfT0pTLZyizVu2f/GbVaiL6 +pgsqeGyKnuh9cNTW5w7Mc45fXkgyKrB4W5aPfjoHN51n+jUqaDrfrp3CoWFviNDn +n3WNFtgrkj/jzQM8XFixhwxADfjd8+sZVmHT4GYjIDS4pCqs5gtIZYKhXDb0Dydj +fH/HiEXC63z0SuFjGNbomC/Era7kI3+1aK2qs6dyASzZKDN6dHKYoalHReUe/Cxk +prRcyYRWhA6lAoIBAEVrLy5Zrd1sLrl4beqdwF0W0lfFLdQj7Kml1KGEIza8EUoI +vy3wcm2naEtkkXrS3tuzOBIgVurp3lbFu8O4Ito8/TSp6uQLe4pzk19qF1ZSpVTU +iHy4AEgtlDfpVL9tl4G3FlpdkiVCnPmrMAd/qOm0oxDNZBcN4fdW3N4EeoKPyy4I +Pt8T2dpormU/vXswPKuoRWAkyFFcEG+Eosa+TGUoqDolAL09ETEQx9XcvbuzXPpK +64FDwGw8vdeaMi/7Y9ck5AFfZZYAG0GYbrTTUthNYSmgkDoh4HBb2/DyZWrMt2f0 +zElVf9bmbbJGXy8GeOT+MAaI4iT6hZvoHn6xqzECggEABoQg6k0LbbSKwPEgEDDN +kbwgEmKd8zD1uFe/50N1ZOEU0LsVUFqmtZlEhtswOSLqkpkqQ868laUb+dpGdz37 +6eyUZxvfQ6hWEZ1JZNhDbuNUhubd+Y4pgJaYf1/owiYt/9BAQ/70jVj5pBQeNsOA +7O/fAD9rfNw4P8fFmq9uBA2wbvKB0kQ0GSlLdFe+SogDgX4UIUhNbOlSqnvzK7da +rWsqRIoyrJwwaXvSduZ/7BXZN/1brLXt/cP6kpk6JN0XpL3MTbLEu6bRyrlHKZT9 +dH2vx75RnCfB5//YwqEUSNYCxpqJH+M4iaHh/slQO0fG1OhwIx278BTyxRBanKDg +3QKCAQBoVnM3PDqaSAT1g3f3neYiXyZektJganRLj5wmDXYAySM2ag/oDacswmP/ +J0BQ9KYK+dSgXldlaXtC05oxdhxY5cawbCFNfbjGDZ6zGwgLDocyFtqOBZf6UXCV +Gtj/9r6iyD2/2wbo/lrS0d3yNcNN0nkZUxoyl+J6uGB1o8bo+cfL+mi4pkALKV8L +Oa/fPazAQtikZBHSWtdQamyUMFSAdMUeYIhaXBfkNUZG4sz9nKD5UGBOmquLMBt6 +zBPM+4dv4x/MEAEnSC2ANW8vDGFBgG/5H5+j2F0RM6O1MlkDzrOAIvUTrMJlJDBt +775JbZNCKpaELqxy4BNPfRDEJGBh +-----END PRIVATE KEY----- +EOH + } + + # The "template" stanza instructs Nomad to manage a template, such as + # a configuration file or script. This template can optionally pull data + # from Consul or Vault to populate runtime configuration data. + # + # https://www.nomadproject.io/docs/job-specification/template + # + template { + change_mode = "noop" + change_signal = "SIGINT" + destination = "secrets/alerts.yml" + left_delimiter = "{{{" + right_delimiter = "}}}" + data = <<EOH +--- +groups: +- name: "Jenkins Job Health Exporter" + rules: + - alert: JenkinsJobHealthExporterFailures + expr: jenkins_job_failure{id=~".*"} > jenkins_job_success{id=~".*"} + for: 0m + labels: + severity: critical + annotations: + summary: "Jenkins Job Health detected high failure rate on jenkins jobs." + description: "Job: {{ $labels.id }}" + - alert: JenkinsJobHealthExporterUnstable + expr: jenkins_job_unstable{id=~".*"} > jenkins_job_success{id=~".*"} + for: 0m + labels: + severity: warning + annotations: + summary: "Jenkins Job Health detected high unstable rate on jenkins jobs." + description: "Job: {{ $labels.id }}" +- name: "Consul" + rules: + - alert: ConsulServiceHealthcheckFailed + expr: consul_catalog_service_node_healthy == 0 + for: 0m + labels: + severity: critical + annotations: + summary: "Consul service healthcheck failed (instance {{ $labels.instance }})." + description: "Service: `{{ $labels.service_name }}` Healthcheck: `{{ $labels.service_id }}`." + - alert: ConsulMissingMasterNode + expr: consul_raft_peers < 3 + for: 0m + labels: + severity: critical + annotations: + summary: "Consul missing master node (instance {{ $labels.instance }})." + description: "Numbers of consul raft peers should be 3, in order to preserve quorum." + - alert: ConsulAgentUnhealthy + expr: consul_health_node_status{status="critical"} == 1 + for: 0m + labels: + severity: critical + annotations: + summary: "Consul agent unhealthy (instance {{ $labels.instance }})." + description: "A Consul agent is down." +- name: "Hosts" + rules: + - alert: NodeDown + expr: up == 0 + for: 0m + labels: + severity: critical + annotations: + summary: "Prometheus target missing (instance {{ $labels.instance }})." + description: "A Prometheus target has disappeared. An exporter might be crashed." + - alert: HostOutOfMemory + expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 < 10 + for: 2m + labels: + severity: warning + annotations: + summary: "Host out of memory (instance {{ $labels.instance }})." + description: "Node memory is filling up (< 10% left)." + - alert: HostOomKillDetected + expr: increase(node_vmstat_oom_kill[1m]) > 0 + for: 0m + labels: + severity: warning + annotations: + summary: "Host OOM kill detected (instance {{ $labels.instance }})." + description: "OOM kill detected." + - alert: HostMemoryUnderMemoryPressure + expr: rate(node_vmstat_pgmajfault[1m]) > 1000 + for: 2m + labels: + severity: warning + annotations: + summary: "Host memory under memory pressure (instance {{ $labels.instance }})." + description: "The node is under heavy memory pressure. High rate of major page faults." + - alert: HostOutOfDiskSpace + expr: (node_filesystem_avail_bytes * 100) / node_filesystem_size_bytes < 10 and ON (instance, device, mountpoint) node_filesystem_readonly == 0 + for: 2m + labels: + severity: warning + annotations: + summary: "Host out of disk space (instance {{ $labels.instance }})." + description: "Disk is almost full (< 10% left)." + - alert: HostRaidDiskFailure + expr: node_md_disks{state="failed"} > 0 + for: 2m + labels: + severity: warning + annotations: + summary: "Host RAID disk failure (instance {{ $labels.instance }})." + description: "At least one device in RAID array on {{ $labels.instance }} failed. Array {{ $labels.md_device }} needs attention and possibly a disk swap." + - alert: HostConntrackLimit + expr: node_nf_conntrack_entries / node_nf_conntrack_entries_limit > 0.8 + for: 5m + labels: + severity: warning + annotations: + summary: "Host conntrack limit (instance {{ $labels.instance }})." + description: "The number of conntrack is approching limit." + - alert: HostNetworkInterfaceSaturated + expr: (rate(node_network_receive_bytes_total{device!~"^tap.*"}[1m]) + rate(node_network_transmit_bytes_total{device!~"^tap.*"}[1m])) / node_network_speed_bytes{device!~"^tap.*"} > 0.8 + for: 1m + labels: + severity: warning + annotations: + summary: "Host Network Interface Saturated (instance {{ $labels.instance }})." + description: "The network interface {{ $labels.interface }} on {{ $labels.instance }} is getting overloaded." + - alert: HostSystemdServiceCrashed + expr: node_systemd_unit_state{state="failed"} == 1 + for: 0m + labels: + severity: warning + annotations: + summary: "Host SystemD service crashed (instance {{ $labels.instance }})." + description: "SystemD service crashed." + - alert: HostEdacCorrectableErrorsDetected + expr: increase(node_edac_correctable_errors_total[1m]) > 0 + for: 0m + labels: + severity: info + annotations: + summary: "Host EDAC Correctable Errors detected (instance {{ $labels.instance }})." + description: '{{ $labels.instance }} has had {{ printf "%.0f" $value }} correctable memory errors reported by EDAC in the last 5 minutes.' + - alert: HostEdacUncorrectableErrorsDetected + expr: node_edac_uncorrectable_errors_total > 0 + for: 0m + labels: + severity: warning + annotations: + summary: "Host EDAC Uncorrectable Errors detected (instance {{ $labels.instance }})." + description: '{{ $labels.instance }} has had {{ printf "%.0f" $value }} uncorrectable memory errors reported by EDAC in the last 5 minutes.' +- name: "Prometheus" + rules: + - alert: PrometheusConfigurationReloadFailure + expr: prometheus_config_last_reload_successful != 1 + for: 0m + labels: + severity: warning + annotations: + summary: "Prometheus configuration reload failure (instance {{ $labels.instance }})." + description: "Prometheus configuration reload error." + - alert: PrometheusTooManyRestarts + expr: changes(process_start_time_seconds{job=~"prometheus|pushgateway|alertmanager"}[15m]) > 2 + for: 0m + labels: + severity: warning + annotations: + summary: "Prometheus too many restarts (instance {{ $labels.instance }})." + description: "Prometheus has restarted more than twice in the last 15 minutes. It might be crashlooping." + - alert: PrometheusAlertmanagerConfigurationReloadFailure + expr: alertmanager_config_last_reload_successful != 1 + for: 0m + labels: + severity: warning + annotations: + summary: "Prometheus AlertManager configuration reload failure (instance {{ $labels.instance }})." + description: "AlertManager configuration reload error." + - alert: PrometheusRuleEvaluationFailures + expr: increase(prometheus_rule_evaluation_failures_total[3m]) > 0 + for: 0m + labels: + severity: critical + annotations: + summary: "Prometheus rule evaluation failures (instance {{ $labels.instance }})." + description: "Prometheus encountered {{ $value }} rule evaluation failures, leading to potentially ignored alerts." + - alert: PrometheusTargetScrapingSlow + expr: prometheus_target_interval_length_seconds{quantile="0.9"} > 60 + for: 5m + labels: + severity: warning + annotations: + summary: "Prometheus target scraping slow (instance {{ $labels.instance }})." + description: "Prometheus is scraping exporters slowly." + - alert: PrometheusTsdbCompactionsFailed + expr: increase(prometheus_tsdb_compactions_failed_total[1m]) > 0 + for: 0m + labels: + severity: critical + annotations: + summary: "Prometheus TSDB compactions failed (instance {{ $labels.instance }})." + description: "Prometheus encountered {{ $value }} TSDB compactions failures." + - alert: PrometheusTsdbHeadTruncationsFailed + expr: increase(prometheus_tsdb_head_truncations_failed_total[1m]) > 0 + for: 0m + labels: + severity: critical + annotations: + summary: "Prometheus TSDB head truncations failed (instance {{ $labels.instance }})." + description: "Prometheus encountered {{ $value }} TSDB head truncation failures." + - alert: PrometheusTsdbWalCorruptions + expr: increase(prometheus_tsdb_wal_corruptions_total[1m]) > 0 + for: 0m + labels: + severity: critical + annotations: + summary: "Prometheus TSDB WAL corruptions (instance {{ $labels.instance }})." + description: "Prometheus encountered {{ $value }} TSDB WAL corruptions." + - alert: PrometheusTsdbWalTruncationsFailed + expr: increase(prometheus_tsdb_wal_truncations_failed_total[1m]) > 0 + for: 0m + labels: + severity: critical + annotations: + summary: "Prometheus TSDB WAL truncations failed (instance {{ $labels.instance }})." + description: "Prometheus encountered {{ $value }} TSDB WAL truncation failures." +EOH + } + + template { + change_mode = "noop" + change_signal = "SIGINT" + destination = "secrets/prometheus.yml" + data = <<EOH +--- +global: + scrape_interval: 5s + scrape_timeout: 5s + evaluation_interval: 5s + +alerting: + alertmanagers: + - consul_sd_configs: + - server: '{{ env "NOMAD_IP_prometheus" }}:8500' + services: [ 'alertmanager' ] + +rule_files: + - 'alerts.yml' + +scrape_configs: + - job_name: 'Nomad Cluster' + consul_sd_configs: + - server: '{{ env "NOMAD_IP_prometheus" }}:8500' + services: [ 'nomad-client', 'nomad' ] + relabel_configs: + - source_labels: [__meta_consul_tags] + regex: '(.*)http(.*)' + action: keep + metrics_path: /v1/metrics + params: + format: [ 'prometheus' ] + + - job_name: 'Consul Cluster' + static_configs: + - targets: [ '10.30.51.23:8500' ] + - targets: [ '10.30.51.24:8500' ] + - targets: [ '10.30.51.25:8500' ] + - targets: [ '10.30.51.26:8500' ] + - targets: [ '10.30.51.27:8500' ] + - targets: [ '10.30.51.28:8500' ] + - targets: [ '10.30.51.50:8500' ] + - targets: [ '10.30.51.51:8500' ] + - targets: [ '10.30.51.70:8500' ] + - targets: [ '10.30.51.71:8500' ] + - targets: [ '10.30.51.91:8500' ] + - targets: [ '10.30.51.92:8500' ] + metrics_path: /v1/agent/metrics + params: + format: [ 'prometheus' ] + + - job_name: 'Jenkins Job Health Exporter' + static_configs: + - targets: [ '10.30.51.22:9186' ] + metric_relabel_configs: + - source_labels: [ __name__ ] + regex: '^(vpp.*|csit.*)_(success|failure|total|unstable|reqtime_ms)$' + action: replace + replacement: '$1' + target_label: id + - source_labels: [ __name__ ] + regex: '^(vpp.*|csit.*)_(success|failure|total|unstable|reqtime_ms)$' + replacement: 'jenkins_job_$2' + target_label: __name__ + + - job_name: 'Node Exporter' + static_configs: + - targets: [ '10.30.51.23:9100' ] + - targets: [ '10.30.51.24:9100' ] + - targets: [ '10.30.51.25:9100' ] + - targets: [ '10.30.51.26:9100' ] + - targets: [ '10.30.51.27:9100' ] + - targets: [ '10.30.51.28:9100' ] + - targets: [ '10.30.51.50:9100' ] + - targets: [ '10.30.51.51:9100' ] + - targets: [ '10.30.51.70:9100' ] + - targets: [ '10.30.51.71:9100' ] + - targets: [ '10.30.51.91:9100' ] + - targets: [ '10.30.51.92:9100' ] + + - job_name: 'Alertmanager' + consul_sd_configs: + - server: '{{ env "NOMAD_IP_prometheus" }}:8500' + services: [ 'alertmanager' ] + + - job_name: 'Prometheus' + honor_timestamps: true + params: + format: + - prometheus + scheme: https + follow_redirects: true + enable_http2: true + consul_sd_configs: + - server: {{ env "CONSUL_HTTP_ADDR" }} + services: + - prometheus + tls_config: + cert_file: cert_file.crt + key_file: key_file.key + insecure_skip_verify: true +EOH + } + + template { + change_mode = "noop" + change_signal = "SIGINT" + destination = "secrets/web-config.yml" + left_delimiter = "{{{" + right_delimiter = "}}}" + data = <<EOH +--- +tls_server_config: + cert_file: cert_file.crt + key_file: key_file.key +EOH + } + + # The service stanza instructs Nomad to register a service with Consul. + # + # https://www.nomadproject.io/docs/job-specification/service + # + service { + name = "${service_name}" + port = "${service_name}" + tags = [ "${service_name}$${NOMAD_ALLOC_INDEX}" ] + check { + name = "Prometheus Check Live" + type = "http" + path = "/-/healthy" + protocol = "https" + tls_skip_verify = true + interval = "10s" + timeout = "2s" + } + } + + # The "resources" stanza describes the requirements a task needs to + # execute. Resource requirements include memory, network, cpu, and more. + # This ensures the task will execute on a machine that contains enough + # resource capacity. + # + # https://www.nomadproject.io/docs/job-specification/resources + # + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-prometheus/fdio/main.tf b/fdio.infra.terraform/terraform-nomad-prometheus/fdio/main.tf new file mode 100644 index 0000000000..054360c838 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-prometheus/fdio/main.tf @@ -0,0 +1,10 @@ +module "prometheus" { + providers = { + nomad = nomad.yul1 + } + source = "../" + + # prometheus + datacenters = ["yul1"] + pm_version = "2.42.0" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-prometheus/fdio/providers.tf b/fdio.infra.terraform/terraform-nomad-prometheus/fdio/providers.tf new file mode 100644 index 0000000000..42a6a45ce0 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-prometheus/fdio/providers.tf @@ -0,0 +1,13 @@ +provider "nomad" { + address = var.nomad_provider_address + alias = "yul1" + # ca_file = var.nomad_provider_ca_file + # cert_file = var.nomad_provider_cert_file + # key_file = var.nomad_provider_key_file +} + +provider "vault" { + address = var.vault_provider_address + skip_tls_verify = var.vault_provider_skip_tls_verify + token = var.vault_provider_token +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-prometheus/fdio/variables.tf b/fdio.infra.terraform/terraform-nomad-prometheus/fdio/variables.tf new file mode 100644 index 0000000000..569ba29c87 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-prometheus/fdio/variables.tf @@ -0,0 +1,47 @@ +variable "nomad_acl" { + description = "Nomad ACLs enabled/disabled." + type = bool + default = false +} + +variable "nomad_provider_address" { + description = "FD.io Nomad cluster address." + type = string + default = "http://10.30.51.23:4646" +} + +variable "nomad_provider_ca_file" { + description = "A local file path to a PEM-encoded certificate authority." + type = string + default = "/etc/nomad.d/ssl/nomad-ca.pem" +} + +variable "nomad_provider_cert_file" { + description = "A local file path to a PEM-encoded certificate." + type = string + default = "/etc/nomad.d/ssl/nomad-cli.pem" +} + +variable "nomad_provider_key_file" { + description = "A local file path to a PEM-encoded private key." + type = string + default = "/etc/nomad.d/ssl/nomad-cli-key.pem" +} + +variable "vault_provider_address" { + description = "Vault cluster address." + type = string + default = "http://10.30.51.23:8200" +} + +variable "vault_provider_skip_tls_verify" { + description = "Verification of the Vault server's TLS certificate." + type = bool + default = false +} + +variable "vault_provider_token" { + description = "Vault root token." + type = string + sensitive = true +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-prometheus/fdio/versions.tf b/fdio.infra.terraform/terraform-nomad-prometheus/fdio/versions.tf new file mode 100644 index 0000000000..97a7173a64 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-prometheus/fdio/versions.tf @@ -0,0 +1,17 @@ +terraform { + backend "consul" { + address = "10.30.51.23:8500" + scheme = "http" + path = "terraform/prometheus" + } + required_providers { + nomad = { + source = "hashicorp/nomad" + version = ">= 1.4.19" + } + vault = { + version = ">= 3.12.0" + } + } + required_version = ">= 1.3.7" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-prometheus/main.tf b/fdio.infra.terraform/terraform-nomad-prometheus/main.tf new file mode 100644 index 0000000000..0c609066e4 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-prometheus/main.tf @@ -0,0 +1,43 @@ +locals { + artifact_source = join("", + [ + "https://github.com", + "/prometheus/prometheus/releases/download/", + "v${var.pm_version}/prometheus-${var.pm_version}.linux-amd64.tar.gz" + ] + ) + datacenters = join(",", var.datacenters) +} + +resource "nomad_job" "nomad_job_prometheus" { + jobspec = templatefile( + "${path.module}/conf/nomad/prometheus.hcl.tftpl", + { + artifact_source = local.artifact_source, + artifact_source_checksum = var.artifact_source_checksum, + auto_promote = var.auto_promote, + auto_revert = var.auto_revert, + canary = var.canary, + cpu = var.cpu, + constraint_value = var.constraint_value, + datacenters = local.datacenters, + group_count = var.group_count, + job_name = var.job_name, + max_parallel = var.max_parallel, + memory = var.memory + port = var.port, + region = var.region, + service_name = var.service_name, + use_canary = var.use_canary, + use_host_volume = var.use_host_volume, + use_vault_provider = var.vault_secret.use_vault_provider, + vault_kv_policy_name = var.vault_secret.vault_kv_policy_name, + vault_kv_path = var.vault_secret.vault_kv_path, + vault_kv_field_access_key = var.vault_secret.vault_kv_field_access_key, + vault_kv_field_secret_key = var.vault_secret.vault_kv_field_secret_key, + version = var.pm_version, + volume_destination = var.volume_destination, + volume_source = var.volume_source + }) + detach = false +} diff --git a/fdio.infra.terraform/terraform-nomad-prometheus/variables.tf b/fdio.infra.terraform/terraform-nomad-prometheus/variables.tf new file mode 100644 index 0000000000..3c8c4b7a26 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-prometheus/variables.tf @@ -0,0 +1,139 @@ +# Nomad +variable "datacenters" { + description = "Specifies the list of DCs to be considered placing this task" + type = list(string) + default = ["dc1"] +} + +variable "region" { + description = "Specifies the list of DCs to be considered placing this task" + type = string + default = "global" +} + +variable "volume_source" { + description = "The name of the volume to request" + type = string + default = "prod-volume-data1-1" +} + +# Prometheus +variable "pm_version" { + description = "Prometheus version" + type = string + default = "2.42.0" +} + +variable "auto_promote" { + description = "Specifies if the job should auto-promote to the canary version" + type = bool + default = true +} + +variable "auto_revert" { + description = "Specifies if the job should auto-revert to the last stable job" + type = bool + default = true +} + +variable "canary" { + description = "Equal to the count of the task group allows blue/green depl." + type = number + default = 1 +} + +variable "cpu" { + description = "CPU allocation" + type = number + default = 2000 +} + +variable "constraint_value" { + description = "The constraint allows restricting the set of eligible nodes." + type = string + default = "builder" +} + +variable "data_dir" { + description = "Prometheus DISK allocation" + type = string + default = "/data" +} + +variable "group_count" { + description = "Specifies the number of the task groups running under this one" + type = number + default = 4 +} + +variable "job_name" { + description = "Specifies a name for the job" + type = string + default = "prometheus" +} + +variable "max_parallel" { + description = "Specifies the maximum number of updates to perform in parallel" + type = number + default = 1 +} + +variable "memory" { + description = "Specifies the memory required in MB" + type = number + default = 4096 +} + +variable "port" { + description = "Specifies the static TCP/UDP port to allocate" + type = number + default = 9090 +} + +variable "service_name" { + description = "Specifies the name this service will be advertised in Consul" + type = string + default = "prometheus" +} + +variable "use_canary" { + description = "Uses canary deployment" + type = bool + default = true +} + +variable "use_host_volume" { + description = "Use Nomad host volume feature" + type = bool + default = true +} + +variable "artifact_source_checksum" { + description = "Prometheus release checksum" + type = string + default = "422dab055ed9c7bcaff52b718705f9192c6fac0de6b7e78dd278e70ee2663dcc" +} + +variable "volume_destination" { + description = "Specifies where the volume should be mounted inside the task" + type = string + default = "/data/" +} + +variable "vault_secret" { + type = object({ + use_vault_provider = bool, + vault_kv_policy_name = string, + vault_kv_path = string, + vault_kv_field_access_key = string, + vault_kv_field_secret_key = string + }) + description = "Set of properties to be able to fetch secret from vault." + default = { + use_vault_provider = false + vault_kv_policy_name = "kv" + vault_kv_path = "secret/data/prometheus" + vault_kv_field_access_key = "access_key" + vault_kv_field_secret_key = "secret_key" + } +} diff --git a/fdio.infra.terraform/terraform-nomad-prometheus/versions.tf b/fdio.infra.terraform/terraform-nomad-prometheus/versions.tf new file mode 100644 index 0000000000..a319c35908 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-prometheus/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + nomad = { + source = "hashicorp/nomad" + version = ">= 1.4.19" + } + } + required_version = ">= 1.3.7" +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/README.md b/fdio.infra.terraform/terraform-nomad-pyspark-etl/README.md new file mode 100644 index 0000000000..d61c8778d4 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/README.md @@ -0,0 +1,50 @@ +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.4 | +| <a name="requirement_nomad"></a> [nomad](#requirement\_nomad) | >= 1.4.20 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_nomad"></a> [nomad](#provider\_nomad) | >= 1.4.20 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [nomad_job.nomad_job](https://registry.terraform.io/providers/hashicorp/nomad/latest/docs/resources/job) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_aws_access_key_id"></a> [aws\_access\_key\_id](#input\_aws\_access\_key\_id) | AWS access key. | `string` | `"aws"` | no | +| <a name="input_aws_default_region"></a> [aws\_default\_region](#input\_aws\_default\_region) | AWS region | `string` | `"aws"` | no | +| <a name="input_aws_secret_access_key"></a> [aws\_secret\_access\_key](#input\_aws\_secret\_access\_key) | AWS secret key | `string` | `"aws"` | no | +| <a name="input_cpu"></a> [cpu](#input\_cpu) | Specifies the CPU required to run this task in MHz. | `number` | `10000` | no | +| <a name="input_cron"></a> [cron](#input\_cron) | Specifies a cron expression configuring the interval to launch. | `string` | `"@daily"` | no | +| <a name="input_datacenters"></a> [datacenters](#input\_datacenters) | Specifies the list of DCs to be considered placing this task. | `list(string)` | <pre>[<br> "dc1"<br>]</pre> | no | +| <a name="input_envs"></a> [envs](#input\_envs) | Specifies ETL environment variables. | `list(string)` | `[]` | no | +| <a name="input_image"></a> [image](#input\_image) | Specifies the Docker image to run. | `string` | `"pmikus/docker-ubuntu-focal-aws-glue:latest"` | no | +| <a name="input_job_name"></a> [job\_name](#input\_job\_name) | Specifies a name for the job. | `string` | `"etl"` | no | +| <a name="input_memory"></a> [memory](#input\_memory) | Specifies the memory required in MB. | `number` | `50000` | no | +| <a name="input_out_aws_access_key_id"></a> [out\_aws\_access\_key\_id](#input\_out\_aws\_access\_key\_id) | AWS access key. | `string` | `"aws"` | no | +| <a name="input_out_aws_default_region"></a> [out\_aws\_default\_region](#input\_out\_aws\_default\_region) | AWS region | `string` | `"aws"` | no | +| <a name="input_out_aws_secret_access_key"></a> [out\_aws\_secret\_access\_key](#input\_out\_aws\_secret\_access\_key) | AWS secret key | `string` | `"aws"` | no | +| <a name="input_prohibit_overlap"></a> [prohibit\_overlap](#input\_prohibit\_overlap) | Specifies if this job should wait until previous completed. | `bool` | `true` | no | +| <a name="input_time_zone"></a> [time\_zone](#input\_time\_zone) | Specifies the time zone to evaluate the next launch interval. | `string` | `"UTC"` | no | +| <a name="input_type"></a> [type](#input\_type) | Specifies the Nomad scheduler to use. | `string` | `"batch"` | no | +| <a name="input_vault_secret"></a> [vault\_secret](#input\_vault\_secret) | Set of properties to be able to fetch secret from vault. | <pre>object({<br> use_vault_provider = bool,<br> vault_kv_policy_name = string,<br> vault_kv_path = string,<br> vault_kv_field_access_key = string,<br> vault_kv_field_secret_key = string<br> })</pre> | <pre>{<br> "use_vault_provider": false,<br> "vault_kv_field_access_key": "access_key",<br> "vault_kv_field_secret_key": "secret_key",<br> "vault_kv_path": "secret/data/etl",<br> "vault_kv_policy_name": "kv"<br>}</pre> | no | + +## Outputs + +No outputs. +<!-- END_TF_DOCS -->
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-device-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-device-rls2402.hcl.tftpl new file mode 100644 index 0000000000..cc0b1df8b5 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-device-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "coverage_device_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-hoststack-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-hoststack-rls2402.hcl.tftpl new file mode 100644 index 0000000000..95d7a4c46e --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-hoststack-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "coverage_hoststack_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-mrr-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-mrr-rls2402.hcl.tftpl new file mode 100644 index 0000000000..3bab9264fa --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-mrr-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "coverage_mrr_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-ndrpdr-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-ndrpdr-rls2402.hcl.tftpl new file mode 100644 index 0000000000..6142219546 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-ndrpdr-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "coverage_ndrpdr_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-reconf-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-reconf-rls2402.hcl.tftpl new file mode 100644 index 0000000000..b474e75217 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-reconf-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "coverage_reconf_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-soak-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-soak-rls2402.hcl.tftpl new file mode 100644 index 0000000000..0352e1e879 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-coverage-soak-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "coverage_soak_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-hoststack-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-hoststack-rls2402.hcl.tftpl new file mode 100644 index 0000000000..74478c59f7 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-hoststack-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "iterative_hoststack_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-mrr-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-mrr-rls2402.hcl.tftpl new file mode 100644 index 0000000000..e6bd87b8ed --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-mrr-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "iterative_mrr_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-ndrpdr-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-ndrpdr-rls2402.hcl.tftpl new file mode 100644 index 0000000000..4a40321377 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-ndrpdr-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "iterative_ndrpdr_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-reconf-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-reconf-rls2402.hcl.tftpl new file mode 100644 index 0000000000..670dd37a11 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-reconf-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "iterative_reconf_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-soak-rls2402.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-soak-rls2402.hcl.tftpl new file mode 100644 index 0000000000..c4ad363879 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-iterative-soak-rls2402.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "20g", + "--executor-memory", "20g", + "--executor-cores", "2", + "--master", "local[2]", + "iterative_soak_rls2402.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-stats.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-stats.hcl.tftpl new file mode 100644 index 0000000000..86ca584de7 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-stats.hcl.tftpl @@ -0,0 +1,53 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "10g", + "--executor-memory", "10g", + "stats.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-hoststack.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-hoststack.hcl.tftpl new file mode 100644 index 0000000000..24aa4095d2 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-hoststack.hcl.tftpl @@ -0,0 +1,53 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "30g", + "--executor-memory", "30g", + "trending_hoststack.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-mrr.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-mrr.hcl.tftpl new file mode 100644 index 0000000000..47d6149eed --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-mrr.hcl.tftpl @@ -0,0 +1,53 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "30g", + "--executor-memory", "30g", + "trending_mrr.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-ndrpdr.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-ndrpdr.hcl.tftpl new file mode 100644 index 0000000000..8cd40f537e --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-ndrpdr.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "30g", + "--executor-memory", "30g", + "--executor-cores", "2", + "--master", "local[2]", + "trending_ndrpdr.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-soak.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-soak.hcl.tftpl new file mode 100644 index 0000000000..6d77a898df --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/conf/nomad/etl-trending-soak.hcl.tftpl @@ -0,0 +1,55 @@ +job "${job_name}" { + datacenters = "${datacenters}" + type = "${type}" + periodic { + cron = "${cron}" + prohibit_overlap = "${prohibit_overlap}" + time_zone = "${time_zone}" + } + group "${job_name}" { + restart { + mode = "fail" + } + constraint { + attribute = "$${attr.cpu.arch}" + operator = "!=" + value = "arm64" + } + constraint { + attribute = "$${node.class}" + value = "builder" + } + task "${job_name}" { + artifact { + source = "git::https://github.com/FDio/csit" + destination = "local/csit" + } + driver = "docker" + config { + image = "${image}" + command = "gluesparksubmit" + args = [ + "--driver-memory", "30g", + "--executor-memory", "30g", + "--executor-cores", "2", + "--master", "local[2]", + "trending_soak.py" + ] + work_dir = "/local/csit/csit.infra.etl" + } + env { + AWS_ACCESS_KEY_ID = "${aws_access_key_id}" + AWS_SECRET_ACCESS_KEY = "${aws_secret_access_key}" + AWS_DEFAULT_REGION = "${aws_default_region}" + OUT_AWS_ACCESS_KEY_ID = "${out_aws_access_key_id}" + OUT_AWS_SECRET_ACCESS_KEY = "${out_aws_secret_access_key}" + OUT_AWS_DEFAULT_REGION = "${out_aws_default_region}" + ${ envs } + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/main.tf b/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/main.tf new file mode 100644 index 0000000000..aac81d9b78 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/main.tf @@ -0,0 +1,283 @@ +data "vault_generic_secret" "fdio_logs" { + path = "kv/secret/data/etl/fdio_logs" +} + +data "vault_generic_secret" "fdio_docs" { + path = "kv/secret/data/etl/fdio_docs" +} + +module "etl-stats" { + providers = { + nomad = nomad.yul1 + } + source = "../" + + aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] + aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] + aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] + out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] + out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] + out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] + cron = "0 30 0 * * * *" + datacenters = ["yul1"] + job_name = "etl-stats" +} + +module "etl-trending-hoststack" { + providers = { + nomad = nomad.yul1 + } + source = "../" + + aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] + aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] + aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] + out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] + out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] + out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] + cron = "0 30 0 * * * *" + datacenters = ["yul1"] + job_name = "etl-trending-hoststack" +} + +module "etl-trending-mrr" { + providers = { + nomad = nomad.yul1 + } + source = "../" + + aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] + aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] + aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] + out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] + out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] + out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] + cron = "0 30 0 * * * *" + datacenters = ["yul1"] + job_name = "etl-trending-mrr" + memory = 60000 +} + +module "etl-trending-ndrpdr" { + providers = { + nomad = nomad.yul1 + } + source = "../" + + aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] + aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] + aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] + out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] + out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] + out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] + cron = "0 30 0 * * * *" + datacenters = ["yul1"] + job_name = "etl-trending-ndrpdr" + memory = 60000 +} + +module "etl-trending-soak" { + providers = { + nomad = nomad.yul1 + } + source = "../" + + aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] + aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] + aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] + out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] + out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] + out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] + cron = "0 30 0 * * * *" + datacenters = ["yul1"] + job_name = "etl-trending-soak" + memory = 60000 +} + +#module "etl-iterative-hoststack-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-iterative-hoststack-rls2402" +#} +# +#module "etl-iterative-mrr-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-iterative-mrr-rls2402" +#} +# +#module "etl-iterative-ndrpdr-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-iterative-ndrpdr-rls2402" +#} +# +#module "etl-iterative-reconf-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-iterative-reconf-rls2402" +#} +# +#module "etl-iterative-soak-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-iterative-soak-rls2402" +#} +# +#module "etl-coverage-device-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-coverage-device-rls2402" +#} +# +#module "etl-coverage-hoststack-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-coverage-hoststack-rls2402" +#} +# +#module "etl-coverage-mrr-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-coverage-mrr-rls2402" +#} +# +#module "etl-coverage-ndrpdr-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-coverage-ndrpdr-rls2402" +#} +# +#module "etl-coverage-reconf-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-coverage-reconf-rls2402" +#} +# +#module "etl-coverage-soak-rls2402" { +# providers = { +# nomad = nomad.yul1 +# } +# source = "../" +# +# aws_access_key_id = data.vault_generic_secret.fdio_logs.data["access_key"] +# aws_secret_access_key = data.vault_generic_secret.fdio_logs.data["secret_key"] +# aws_default_region = data.vault_generic_secret.fdio_logs.data["region"] +# out_aws_access_key_id = data.vault_generic_secret.fdio_docs.data["access_key"] +# out_aws_secret_access_key = data.vault_generic_secret.fdio_docs.data["secret_key"] +# out_aws_default_region = data.vault_generic_secret.fdio_docs.data["region"] +# cron = "0 30 0 * * * *" +# datacenters = ["yul1"] +# job_name = "etl-coverage-soak-rls2402" +#} +#
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/providers.tf b/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/providers.tf new file mode 100644 index 0000000000..c6617da02b --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/providers.tf @@ -0,0 +1,13 @@ +provider "nomad" { + address = var.nomad_provider_address + alias = "yul1" + # ca_file = var.nomad_provider_ca_file + # cert_file = var.nomad_provider_cert_file + # key_file = var.nomad_provider_key_file +} + +provider "vault" { + address = var.vault_provider_address + skip_tls_verify = var.vault_provider_skip_tls_verify + token = var.vault_provider_token +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/variables.tf b/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/variables.tf new file mode 100644 index 0000000000..db24bdf0fa --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/variables.tf @@ -0,0 +1,47 @@ +variable "nomad_acl" { + description = "Nomad ACLs enabled/disabled." + type = bool + default = false +} + +variable "nomad_provider_address" { + description = "FD.io Nomad cluster address." + type = string + default = "http://10.30.51.23:4646" +} + +variable "nomad_provider_ca_file" { + description = "A local file path to a PEM-encoded certificate authority." + type = string + default = "/etc/nomad.d/ssl/nomad-ca.pem" +} + +variable "nomad_provider_cert_file" { + description = "A local file path to a PEM-encoded certificate." + type = string + default = "/etc/nomad.d/ssl/nomad-cli.pem" +} + +variable "nomad_provider_key_file" { + description = "A local file path to a PEM-encoded private key." + type = string + default = "/etc/nomad.d/ssl/nomad-cli-key.pem" +} + +variable "vault_provider_address" { + description = "Vault cluster address." + type = string + default = "http://10.30.51.23:8200" +} + +variable "vault_provider_skip_tls_verify" { + description = "Verification of the Vault server's TLS certificate." + type = bool + default = false +} + +variable "vault_provider_token" { + description = "Vault root token." + type = string + sensitive = true +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/versions.tf b/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/versions.tf new file mode 100644 index 0000000000..0c05e76d65 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/fdio/versions.tf @@ -0,0 +1,17 @@ +terraform { + backend "consul" { + address = "10.30.51.23:8500" + scheme = "http" + path = "terraform/etl" + } + required_providers { + nomad = { + source = "hashicorp/nomad" + version = ">= 1.4.20" + } + vault = { + version = ">= 3.12.0" + } + } + required_version = ">= 1.5.4" +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/main.tf b/fdio.infra.terraform/terraform-nomad-pyspark-etl/main.tf new file mode 100644 index 0000000000..cd6a9a52ff --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/main.tf @@ -0,0 +1,33 @@ +locals { + datacenters = join(",", var.datacenters) + envs = join("\n", concat([], var.envs)) +} + +resource "nomad_job" "nomad_job" { + jobspec = templatefile( + "${path.module}/conf/nomad/${var.job_name}.hcl.tftpl", + { + aws_access_key_id = var.aws_access_key_id, + aws_secret_access_key = var.aws_secret_access_key, + aws_default_region = var.aws_default_region + cpu = var.cpu, + cron = var.cron, + datacenters = local.datacenters, + envs = local.envs, + image = var.image, + job_name = var.job_name, + memory = var.memory, + out_aws_access_key_id = var.out_aws_access_key_id, + out_aws_secret_access_key = var.out_aws_secret_access_key, + out_aws_default_region = var.out_aws_default_region + prohibit_overlap = var.prohibit_overlap, + time_zone = var.time_zone, + type = var.type, + use_vault_provider = var.vault_secret.use_vault_provider, + vault_kv_policy_name = var.vault_secret.vault_kv_policy_name, + vault_kv_path = var.vault_secret.vault_kv_path, + vault_kv_field_access_key = var.vault_secret.vault_kv_field_access_key, + vault_kv_field_secret_key = var.vault_secret.vault_kv_field_secret_key + }) + detach = false +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/variables.tf b/fdio.infra.terraform/terraform-nomad-pyspark-etl/variables.tf new file mode 100644 index 0000000000..f6d318e855 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/variables.tf @@ -0,0 +1,115 @@ +# Nomad +variable "datacenters" { + description = "Specifies the list of DCs to be considered placing this task." + type = list(string) + default = ["dc1"] +} + +# ETL +variable "aws_access_key_id" { + description = "AWS access key." + type = string + default = "aws" +} + +variable "aws_secret_access_key" { + description = "AWS secret key" + type = string + default = "aws" +} + +variable "aws_default_region" { + description = "AWS region" + type = string + default = "aws" +} + +variable "cpu" { + description = "Specifies the CPU required to run this task in MHz." + type = number + default = 10000 +} + +variable "cron" { + description = "Specifies a cron expression configuring the interval to launch." + type = string + default = "@daily" +} + +variable "envs" { + description = "Specifies ETL environment variables." + type = list(string) + default = [] +} + +variable "image" { + description = "Specifies the Docker image to run." + type = string + default = "pmikus/docker-ubuntu-focal-aws-glue:latest" +} + +variable "job_name" { + description = "Specifies a name for the job." + type = string + default = "etl" +} + +variable "memory" { + description = "Specifies the memory required in MB." + type = number + default = 50000 +} + +variable "out_aws_access_key_id" { + description = "AWS access key." + type = string + default = "aws" +} + +variable "out_aws_secret_access_key" { + description = "AWS secret key" + type = string + default = "aws" +} + +variable "out_aws_default_region" { + description = "AWS region" + type = string + default = "aws" +} + +variable "prohibit_overlap" { + description = "Specifies if this job should wait until previous completed." + type = bool + default = true +} + +variable "time_zone" { + description = "Specifies the time zone to evaluate the next launch interval." + type = string + default = "UTC" +} + +variable "type" { + description = "Specifies the Nomad scheduler to use." + type = string + default = "batch" +} + +variable "vault_secret" { + type = object({ + use_vault_provider = bool, + vault_kv_policy_name = string, + vault_kv_path = string, + vault_kv_field_access_key = string, + vault_kv_field_secret_key = string + }) + description = "Set of properties to be able to fetch secret from vault." + default = { + use_vault_provider = false + vault_kv_policy_name = "kv" + vault_kv_path = "secret/data/etl" + vault_kv_field_access_key = "access_key" + vault_kv_field_secret_key = "secret_key" + } +} diff --git a/fdio.infra.terraform/terraform-nomad-pyspark-etl/versions.tf b/fdio.infra.terraform/terraform-nomad-pyspark-etl/versions.tf new file mode 100644 index 0000000000..f40435fe77 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-pyspark-etl/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + nomad = { + source = "hashicorp/nomad" + version = ">= 1.4.20" + } + } + required_version = ">= 1.5.4" +} diff --git a/fdio.infra.terraform/terraform-nomad-vpp-device/conf/nomad/device-shim.hcl.tftpl b/fdio.infra.terraform/terraform-nomad-vpp-device/conf/nomad/device-shim.hcl.tftpl new file mode 100644 index 0000000000..28e38a2d0b --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-vpp-device/conf/nomad/device-shim.hcl.tftpl @@ -0,0 +1,78 @@ +job "${job_name}" { + datacenters = ["${datacenters}"] + type = "system" + group "${job_name}-amd" { + count = ${group_count} + constraint { + attribute = "$${node.class}" + value = "csit" + } + restart { + interval = "1m" + attempts = 3 + delay = "15s" + mode = "delay" + } + network { + port "ssh" { + static = 6022 + } + port "ssh2" { + static = 6023 + } + } + task "${job_name}-amd" { + driver = "docker" + config { + image = "${image_x86_64}" + network_mode = "host" + pid_mode = "host" + volumes = [ + "/var/run/docker.sock:/var/run/docker.sock" + ] + privileged = true + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } + group "${job_name}-arm" { + count = ${group_count} + constraint { + attribute = "$${node.class}" + value = "csitarm" + } + restart { + interval = "1m" + attempts = 3 + delay = "15s" + mode = "delay" + } + network { + port "ssh" { + static = 6022 + } + port "ssh2" { + static = 6023 + } + } + task "${job_name}-arm" { + driver = "docker" + config { + image = "${image_aarch64}" + network_mode = "host" + pid_mode = "host" + volumes = [ + "/var/run/docker.sock:/var/run/docker.sock" + ] + privileged = true + } + resources { + cpu = ${cpu} + memory = ${memory} + } + } + } +} diff --git a/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/main.tf b/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/main.tf new file mode 100644 index 0000000000..a6217d781f --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/main.tf @@ -0,0 +1,16 @@ +module "vpp-device" { + providers = { + nomad = nomad.yul1 + } + source = "../" + + # nomad + datacenters = ["yul1"] + job_name = "device-shim" + group_count = 1 + cpu = 1500 + memory = 4096 + image_aarch64 = "fdiotools/csit_shim-ubuntu2004:2021_03_02_143938_UTC-aarch64" + image_x86_64 = "fdiotools/csit_shim-ubuntu2004:2021_03_04_142103_UTC-x86_64" +} + diff --git a/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/providers.tf b/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/providers.tf new file mode 100644 index 0000000000..42a6a45ce0 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/providers.tf @@ -0,0 +1,13 @@ +provider "nomad" { + address = var.nomad_provider_address + alias = "yul1" + # ca_file = var.nomad_provider_ca_file + # cert_file = var.nomad_provider_cert_file + # key_file = var.nomad_provider_key_file +} + +provider "vault" { + address = var.vault_provider_address + skip_tls_verify = var.vault_provider_skip_tls_verify + token = var.vault_provider_token +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/variables.tf b/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/variables.tf new file mode 100644 index 0000000000..569ba29c87 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/variables.tf @@ -0,0 +1,47 @@ +variable "nomad_acl" { + description = "Nomad ACLs enabled/disabled." + type = bool + default = false +} + +variable "nomad_provider_address" { + description = "FD.io Nomad cluster address." + type = string + default = "http://10.30.51.23:4646" +} + +variable "nomad_provider_ca_file" { + description = "A local file path to a PEM-encoded certificate authority." + type = string + default = "/etc/nomad.d/ssl/nomad-ca.pem" +} + +variable "nomad_provider_cert_file" { + description = "A local file path to a PEM-encoded certificate." + type = string + default = "/etc/nomad.d/ssl/nomad-cli.pem" +} + +variable "nomad_provider_key_file" { + description = "A local file path to a PEM-encoded private key." + type = string + default = "/etc/nomad.d/ssl/nomad-cli-key.pem" +} + +variable "vault_provider_address" { + description = "Vault cluster address." + type = string + default = "http://10.30.51.23:8200" +} + +variable "vault_provider_skip_tls_verify" { + description = "Verification of the Vault server's TLS certificate." + type = bool + default = false +} + +variable "vault_provider_token" { + description = "Vault root token." + type = string + sensitive = true +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/versions.tf b/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/versions.tf new file mode 100644 index 0000000000..fc5a3ab12d --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-vpp-device/fdio/versions.tf @@ -0,0 +1,15 @@ +terraform { + backend "consul" { + address = "10.30.51.23:8500" + scheme = "http" + path = "terraform/device-csit-shim" + } + required_providers { + nomad = { + source = "hashicorp/nomad" + version = ">= 1.4.20" + } + } + required_version = ">= 1.5.4" +} + diff --git a/fdio.infra.terraform/terraform-nomad-vpp-device/main.tf b/fdio.infra.terraform/terraform-nomad-vpp-device/main.tf new file mode 100644 index 0000000000..b176172d00 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-vpp-device/main.tf @@ -0,0 +1,20 @@ +locals { + datacenters = join(",", var.datacenters) +} + +resource "nomad_job" "nomad_job" { + jobspec = templatefile( + "${path.module}/conf/nomad/${var.job_name}.hcl.tftpl", + { + datacenters = local.datacenters, + job_name = var.job_name, + group_count = var.group_count, + cpu = var.cpu, + memory = var.memory, + image_aarch64 = var.image_aarch64, + image_x86_64 = var.image_x86_64 + } + ) + detach = false +} + diff --git a/fdio.infra.terraform/terraform-nomad-vpp-device/variables.tf b/fdio.infra.terraform/terraform-nomad-vpp-device/variables.tf new file mode 100644 index 0000000000..0a11e1da3b --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-vpp-device/variables.tf @@ -0,0 +1,43 @@ +# Nomad +variable "datacenters" { + description = "Specifies the list of DCs to be considered placing this task" + type = list(string) + default = ["dc1"] +} + +# CSIT SHIM +variable "job_name" { + description = "CSIT SHIM job name" + type = string + default = "prod-csit-shim" +} + +variable "group_count" { + description = "Number of CSIT SHIM group instances" + type = number + default = 1 +} + +variable "cpu" { + description = "CSIT SHIM task CPU" + type = number + default = 2000 +} + +variable "memory" { + description = "CSIT SHIM task memory" + type = number + default = 10000 +} + +variable "image_aarch64" { + description = "CSIT SHIM AARCH64 docker image" + type = string + default = "fdiotools/csit_shim-ubuntu2004:prod-aarch64" +} + +variable "image_x86_64" { + description = "CSIT SHIM X86_64 docker image" + type = string + default = "fdiotools/csit_shim-ubuntu2004:prod-x86_64" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-nomad-vpp-device/versions.tf b/fdio.infra.terraform/terraform-nomad-vpp-device/versions.tf new file mode 100644 index 0000000000..f40435fe77 --- /dev/null +++ b/fdio.infra.terraform/terraform-nomad-vpp-device/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + nomad = { + source = "hashicorp/nomad" + version = ">= 1.4.20" + } + } + required_version = ">= 1.5.4" +} diff --git a/fdio.infra.terraform/terraform-openstack-2n/README.md b/fdio.infra.terraform/terraform-openstack-2n/README.md new file mode 100644 index 0000000000..3ddb0f3789 --- /dev/null +++ b/fdio.infra.terraform/terraform-openstack-2n/README.md @@ -0,0 +1,58 @@ +# terraform-openstack-2n-generic +Terraform module to create 2n-generic topology. + +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.4.2 | +| <a name="requirement_openstack"></a> [openstack](#requirement\_openstack) | ~> 1.53.0 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_local"></a> [local](#provider\_local) | 2.4.1 | +| <a name="provider_openstack"></a> [openstack](#provider\_openstack) | 1.53.0 | +| <a name="provider_template"></a> [template](#provider\_template) | 2.2.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| <a name="module_openstack_compute_keypair_v2"></a> [openstack\_compute\_keypair\_v2](#module\_openstack\_compute\_keypair\_v2) | pmikus/compute-keypair-v2/openstack | 1.54.1 | +| <a name="module_openstack_images_image_v2"></a> [openstack\_images\_image\_v2](#module\_openstack\_images\_image\_v2) | pmikus/images-image-v2/openstack | 1.54.1 | +| <a name="module_sut1"></a> [sut1](#module\_sut1) | pmikus/compute-instance-v2/openstack | 1.54.1 | +| <a name="module_tg1"></a> [tg1](#module\_tg1) | pmikus/compute-instance-v2/openstack | 1.54.1 | + +## Resources + +| Name | Type | +|------|------| +| [local_file.hosts](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | +| [local_file.topology_file](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | +| [openstack_networking_port_v2.port_sut1_data1](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_port_v2) | resource | +| [openstack_networking_port_v2.port_sut1_data2](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_port_v2) | resource | +| [openstack_networking_port_v2.port_sut1_mgmt](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_port_v2) | resource | +| [openstack_networking_port_v2.port_tg1_data1](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_port_v2) | resource | +| [openstack_networking_port_v2.port_tg1_data2](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_port_v2) | resource | +| [openstack_networking_port_v2.port_tg1_mgmt](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/resources/networking_port_v2) | resource | +| [template_cloudinit_config.cloudinit_config_sut1](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config) | data source | +| [template_cloudinit_config.cloudinit_config_tg1](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_flavour_name"></a> [flavour\_name](#input\_flavour\_name) | (Optional; Required if flavor\_id is empty) The name of the desired flavor for the server. Changing this resizes the existing server. | `string` | n/a | yes | +| <a name="input_network_id_data"></a> [network\_id\_data](#input\_network\_id\_data) | (Required) The ID of the network to attach the port to. Changing this creates a new port. | `string` | n/a | yes | +| <a name="input_network_id_mgmt"></a> [network\_id\_mgmt](#input\_network\_id\_mgmt) | (Required) The ID of the network to attach the port to. Changing this creates a new port. | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| <a name="output_sut_id"></a> [sut\_id](#output\_sut\_id) | SUT VM ID. | +| <a name="output_tg_id"></a> [tg\_id](#output\_tg\_id) | TG VM ID. | +<!-- END_TF_DOCS --> diff --git a/fdio.infra.terraform/terraform-openstack-2n/hosts.tftpl b/fdio.infra.terraform/terraform-openstack-2n/hosts.tftpl new file mode 100644 index 0000000000..cb36dbb138 --- /dev/null +++ b/fdio.infra.terraform/terraform-openstack-2n/hosts.tftpl @@ -0,0 +1,8 @@ +all: + children: + tg: + hosts: + ${tg_public_ip} + sut: + hosts: + ${dut1_public_ip}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-openstack-2n/main.tf b/fdio.infra.terraform/terraform-openstack-2n/main.tf new file mode 100644 index 0000000000..f306933a81 --- /dev/null +++ b/fdio.infra.terraform/terraform-openstack-2n/main.tf @@ -0,0 +1,211 @@ +locals { + image_name = "Ubuntu 22.04.2 LTS" + image_source_url = "http://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img" + resource_prefix = "csit-2n" + testbed_name = "xu6n" + topology_name = "2n" +} + +# Create Cloud-Init config for TG. +data "template_cloudinit_config" "cloudinit_config_tg1" { + gzip = false + base64_encode = false + + part { + content_type = "text/cloud-config" + content = templatefile( + "${path.module}/user-data-tg1", {} + ) + } +} + +# Create Cloud-Init config for SUT1. +data "template_cloudinit_config" "cloudinit_config_sut1" { + gzip = false + base64_encode = false + + part { + content_type = "text/cloud-config" + content = templatefile( + "${path.module}/user-data-sut1", {} + ) + } +} + +# Create OpenStack Image. +module "openstack_images_image_v2" { + source = "pmikus/images-image-v2/openstack" + version = "1.54.1" + + image_source_url = local.image_source_url + name = local.image_name +} + +# Create OpenStack Keypair. +module "openstack_compute_keypair_v2" { + source = "pmikus/compute-keypair-v2/openstack" + version = "1.54.1" + + name = "${local.resource_prefix}-keypair" +} + + +# Create management port in dedicated subnet. +resource "openstack_networking_port_v2" "port_tg1_mgmt" { + admin_state_up = true + fixed_ip { + ip_address = "10.21.152.2" + subnet_id = "b1f9573d-4c2e-45da-bbac-cb3f191ab0f5" + } + name = "${local.resource_prefix}-tg1-mgmt-port" + network_id = var.network_id_mgmt + port_security_enabled = false + + binding { + vnic_type = "normal" + } +} + +# Create data port in dedicated subnet. +resource "openstack_networking_port_v2" "port_tg1_data1" { + admin_state_up = false + name = "${local.resource_prefix}-tg1-data1-port" + network_id = var.network_id_data + port_security_enabled = false + + binding { + vnic_type = "direct" + } +} + +# Create data port in dedicated subnet. +resource "openstack_networking_port_v2" "port_tg1_data2" { + admin_state_up = false + name = "${local.resource_prefix}-tg1-data2-port" + network_id = var.network_id_data + port_security_enabled = false + + binding { + vnic_type = "direct" + } +} + +# Create TG instance. +module "tg1" { + depends_on = [ + module.openstack_compute_keypair_v2, + module.openstack_images_image_v2 + ] + + source = "pmikus/compute-instance-v2/openstack" + version = "1.54.1" + + flavour_name = var.flavour_name + image_id = module.openstack_images_image_v2.id + key_pair = module.openstack_compute_keypair_v2.name + name = "${local.resource_prefix}-tg1" + networks = { + "platform-shared-port" = openstack_networking_port_v2.port_tg1_mgmt.id + "data-playground-port1" = openstack_networking_port_v2.port_tg1_data1.id + "data-playground-port2" = openstack_networking_port_v2.port_tg1_data2.id + } + user_data = data.template_cloudinit_config.cloudinit_config_tg1.rendered +} + +# Create management port in dedicated subnet. +resource "openstack_networking_port_v2" "port_sut1_mgmt" { + admin_state_up = true + fixed_ip { + ip_address = "10.21.152.3" + subnet_id = "b1f9573d-4c2e-45da-bbac-cb3f191ab0f5" + } + name = "${local.resource_prefix}-sut1-mgmt-port" + network_id = var.network_id_mgmt + port_security_enabled = false + + binding { + vnic_type = "normal" + } +} + +# Create data port in dedicated subnet. +resource "openstack_networking_port_v2" "port_sut1_data1" { + admin_state_up = false + name = "${local.resource_prefix}-sut1-data1-port" + network_id = var.network_id_data + port_security_enabled = false + + binding { + vnic_type = "direct" + } +} + +# Create data port in dedicated subnet. +resource "openstack_networking_port_v2" "port_sut1_data2" { + admin_state_up = false + name = "${local.resource_prefix}-sut1-data2-port" + network_id = var.network_id_data + port_security_enabled = false + + binding { + vnic_type = "direct" + } +} + +# Create SUT instance. +module "sut1" { + depends_on = [ + module.openstack_compute_keypair_v2, + module.openstack_images_image_v2 + ] + + source = "pmikus/compute-instance-v2/openstack" + version = "1.54.1" + + flavour_name = var.flavour_name + image_id = module.openstack_images_image_v2.id + key_pair = module.openstack_compute_keypair_v2.name + name = "${local.resource_prefix}-sut1" + networks = { + "platform-shared-port" = openstack_networking_port_v2.port_sut1_mgmt.id + "data-playground-port1" = openstack_networking_port_v2.port_sut1_data1.id + "data-playground-port2" = openstack_networking_port_v2.port_sut1_data2.id + } + user_data = data.template_cloudinit_config.cloudinit_config_sut1.rendered +} + +resource "local_file" "topology_file" { + depends_on = [ + module.tg1, + module.sut1 + ] + + content = templatefile( + "${path.module}/topology-${local.topology_name}.tftpl", + { + tg_if1_mac = openstack_networking_port_v2.port_tg1_data1.mac_address + tg_if2_mac = openstack_networking_port_v2.port_tg1_data2.mac_address + dut1_if1_mac = openstack_networking_port_v2.port_sut1_data1.mac_address + dut1_if2_mac = openstack_networking_port_v2.port_sut1_data2.mac_address + tg_public_ip = openstack_networking_port_v2.port_tg1_mgmt.fixed_ip[0].ip_address + dut1_public_ip = openstack_networking_port_v2.port_sut1_mgmt.fixed_ip[0].ip_address + } + ) + filename = "${path.module}/${local.topology_name}-x-${local.testbed_name}.yaml" +} + +resource "local_file" "hosts" { + depends_on = [ + module.tg1, + module.sut1 + ] + + content = templatefile( + "${path.module}/hosts.tftpl", + { + tg_public_ip = openstack_networking_port_v2.port_tg1_mgmt.fixed_ip[0].ip_address + dut1_public_ip = openstack_networking_port_v2.port_sut1_mgmt.fixed_ip[0].ip_address + } + ) + filename = "${path.module}/hosts.yaml" +} diff --git a/fdio.infra.terraform/terraform-openstack-2n/outputs.tf b/fdio.infra.terraform/terraform-openstack-2n/outputs.tf new file mode 100644 index 0000000000..f8985685f0 --- /dev/null +++ b/fdio.infra.terraform/terraform-openstack-2n/outputs.tf @@ -0,0 +1,9 @@ +output "tg_id" { + description = "TG VM ID." + value = module.tg1.id +} + +output "sut_id" { + description = "SUT VM ID." + value = module.sut1.id +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-openstack-2n/topology-2n.tftpl b/fdio.infra.terraform/terraform-openstack-2n/topology-2n.tftpl new file mode 100644 index 0000000000..1129a6f8f3 --- /dev/null +++ b/fdio.infra.terraform/terraform-openstack-2n/topology-2n.tftpl @@ -0,0 +1,59 @@ +--- +metadata: + version: 0.1 + schema: + - resources/topology_schemas/2_node_topology.sch.yaml + - resources/topology_schemas/topology.sch.yaml + tags: [hw, 2-node] + +nodes: + TG: + type: TG + subtype: TREX + host: "${tg_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + interfaces: + port1: + # tg_instance/p1 - 100GE port1 on E810 NIC. + mac_address: "${tg_if1_mac}" + pci_address: "0000:00:05.0" + ip4_address: "172.16.10.2" + driver: iavf + link: link1 + model: Intel-E810 + port2: + # tg_instance/p2 - 100GE port2 on E810 NIC. + mac_address: "${tg_if2_mac}" + pci_address: "0000:00:06.0" + ip4_address: "172.16.20.2" + driver: iavf + link: link2 + model: Intel-E810 + DUT1: + type: DUT + host: "${dut1_public_ip}" + arch: x86_64 + port: 22 + username: testuser + password: Csit1234 + uio_driver: vfio-pci + interfaces: + port1: + # dut1_instance/p1 - 100GE port1 on E810 NIC. + mac_address: "${dut1_if1_mac}" + pci_address: "0000:00:05.0" + ip4_address: "172.16.10.1" + driver: iavf + link: link1 + model: Intel-E810 + port2: + # dut1_instance/p2 - 100GE port2 on E810 NIC. + mac_address: "${dut1_if2_mac}" + pci_address: "0000:00:06.0" + ip4_address: "172.16.20.1" + driver: iavf + link: link2 + model: Intel-E810
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-openstack-2n/user-data-sut1 b/fdio.infra.terraform/terraform-openstack-2n/user-data-sut1 new file mode 100644 index 0000000000..9838f1b165 --- /dev/null +++ b/fdio.infra.terraform/terraform-openstack-2n/user-data-sut1 @@ -0,0 +1,66 @@ +#cloud-config +apt: + sources: + docker.list: + source: "deb [arch=amd64] https://download.docker.com/linux/ubuntu $RELEASE stable" + keyid: "9DC858229FC7DD38854AE2D88D81803C0EBFCD88" +groups: + - "docker" +hostname: "s02-t21-sut1" +package_update: true +packages: + - "apt-transport-https" + - "autoconf" + - "build-essential" + - "ca-certificates" + - "cgroup-tools" + - "curl" + - "dkms" + - "docker-ce" + - "docker-ce-cli" + - "gdb" + - "gnupg-agent" + - "iperf3" + - "libglib2.0-dev" + - "libmbedcrypto7" + - "libmbedtls14" + - "libmbedx509-1" + - "libnuma-dev" + - "libpixman-1-dev" + - "libpcap-dev" + - "libtool" + - "linux-tools-common" + - "lxc" + - "net-tools" + - "ninja-build" + - "numactl" + - "pkg-config" + - "python3-all" + - "python3-apt" + - "python3-cffi" + - "python3-cffi-backend" + - "python3-dev" + - "python3-pip" + - "python3-pyelftools" + - "python3-setuptools" + - "qemu-system" + - "screen" + - "socat" + - "software-properties-common" + - "unzip" + - "virtualenv" +runcmd: + - sed -i '/PermitRootLogin/d' /etc/ssh/sshd_config + - echo "PermitRootLogin no" >> /etc/ssh/sshd_config + - systemctl restart sshd + - systemctl start docker + - systemctl enable docker +ssh_pwauth: True +users: + - name: "testuser" + groups: users, admin, docker, sudo + shell: "/bin/bash" + sudo: + - ALL=(ALL) NOPASSWD:ALL + lock_passwd: false + passwd: "$6$Y62lhMGJD8YNzmJn$H4DSqjrwFp5WN3tOvIrF.g/G2duOV76zXHAmaA/RU8jfT8H8sDumLQe/Q.EmI5pjPv7dzgI8j9BQPWes7efBK0"
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-openstack-2n/user-data-tg1 b/fdio.infra.terraform/terraform-openstack-2n/user-data-tg1 new file mode 100644 index 0000000000..59f6a481db --- /dev/null +++ b/fdio.infra.terraform/terraform-openstack-2n/user-data-tg1 @@ -0,0 +1,71 @@ +#cloud-config +apt: + sources: + docker.list: + source: "deb [arch=amd64] https://download.docker.com/linux/ubuntu $RELEASE stable" + keyid: "9DC858229FC7DD38854AE2D88D81803C0EBFCD88" +groups: + - "docker" +hostname: "s01-t21-tg" +package_update: true +packages: + - "apt-transport-https" + - "autoconf" + - "build-essential" + - "ca-certificates" + - "cgroup-tools" + - "curl" + - "dkms" + - "docker-ce" + - "docker-ce-cli" + - "gcc-9" + - "g++-9" + - "gnupg-agent" + - "iperf3" + - "libmnl-dev" + - "libnuma-dev" + - "libpcap-dev" + - "librdmacm-dev" + - "librdmacm1" + - "libssl-dev" + - "linux-tools-common" + - "net-tools" + - "ninja-build" + - "numactl" + - "pciutils" + - "python3-all" + - "python3-apt" + - "python3-cffi" + - "python3-cffi-backend" + - "python3-dev" + - "python3-pip" + - "python3-pyelftools" + - "python3-setuptools" + - "qemu-system" + - "socat" + - "software-properties-common" + - "unzip" + - "virtualenv" + - "zlib1g-dev" +runcmd: + - sed -i '/PermitRootLogin/d' /etc/ssh/sshd_config + - echo "PermitRootLogin no" >> /etc/ssh/sshd_config + - systemctl restart sshd + - systemctl start docker + - systemctl enable docker + - curl --proxy "http://[2620:0:cc8:11::1]:8888" -L http://github.com/cisco-system-traffic-generator/trex-core/archive/v3.03.tar.gz -o /opt/trex-core-v3.03.tar.gz + - mkdir -p /opt/trex-core-v3.03 + - tar xzf /opt/trex-core-v3.03.tar.gz -C /opt/trex-core-v3.03 --strip-components=1 + - cd /opt/trex-core-v3.03/linux_dpdk && ./b configure + - cd /opt/trex-core-v3.03/linux_dpdk && ./b build + - cd /opt/trex-core-v3.03/scripts/ko/src && make + - cd /opt/trex-core-v3.03/scripts/ko/src && make install +ssh_pwauth: True +users: + - name: "testuser" + groups: users, admin, docker, sudo + shell: "/bin/bash" + sudo: + - ALL=(ALL) NOPASSWD:ALL + lock_passwd: false + passwd: "$6$Y62lhMGJD8YNzmJn$H4DSqjrwFp5WN3tOvIrF.g/G2duOV76zXHAmaA/RU8jfT8H8sDumLQe/Q.EmI5pjPv7dzgI8j9BQPWes7efBK0" diff --git a/fdio.infra.terraform/terraform-openstack-2n/variables.tf b/fdio.infra.terraform/terraform-openstack-2n/variables.tf new file mode 100644 index 0000000000..d761016699 --- /dev/null +++ b/fdio.infra.terraform/terraform-openstack-2n/variables.tf @@ -0,0 +1,14 @@ +variable "flavour_name" { + description = "(Optional; Required if flavor_id is empty) The name of the desired flavor for the server. Changing this resizes the existing server." + type = string +} + +variable "network_id_data" { + description = "(Required) The ID of the network to attach the port to. Changing this creates a new port." + type = string +} + +variable "network_id_mgmt" { + description = "(Required) The ID of the network to attach the port to. Changing this creates a new port." + type = string +} diff --git a/fdio.infra.terraform/terraform-openstack-2n/versions.tf b/fdio.infra.terraform/terraform-openstack-2n/versions.tf new file mode 100644 index 0000000000..1ad4a215b5 --- /dev/null +++ b/fdio.infra.terraform/terraform-openstack-2n/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + openstack = { + source = "terraform-provider-openstack/openstack" + version = "~> 1.53.0" + } + } + required_version = ">= 1.4.2" +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-vault-aws-secret-backend/README.md b/fdio.infra.terraform/terraform-vault-aws-secret-backend/README.md new file mode 100644 index 0000000000..af0fa29334 --- /dev/null +++ b/fdio.infra.terraform/terraform-vault-aws-secret-backend/README.md @@ -0,0 +1,40 @@ +<!-- BEGIN_TF_DOCS --> +## Requirements + +| Name | Version | +|------|---------| +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.4 | +| <a name="requirement_vault"></a> [vault](#requirement\_vault) | >=2.22.1 | + +## Providers + +| Name | Version | +|------|---------| +| <a name="provider_vault"></a> [vault](#provider\_vault) | >=2.22.1 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [vault_aws_secret_backend.aws](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/resources/aws_secret_backend) | resource | +| [vault_aws_secret_backend_role.admin](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/resources/aws_secret_backend_role) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| <a name="input_aws_access_key"></a> [aws\_access\_key](#input\_aws\_access\_key) | AWS access key | `string` | n/a | yes | +| <a name="input_aws_secret_key"></a> [aws\_secret\_key](#input\_aws\_secret\_key) | AWS secret key | `string` | n/a | yes | +| <a name="input_name"></a> [name](#input\_name) | Vault path | `string` | `"dynamic-aws-creds-vault"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| <a name="output_backend"></a> [backend](#output\_backend) | n/a | +| <a name="output_role"></a> [role](#output\_role) | n/a | +<!-- END_TF_DOCS -->
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/main.tf b/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/main.tf new file mode 100644 index 0000000000..4473dafda8 --- /dev/null +++ b/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/main.tf @@ -0,0 +1,17 @@ +module "fdio-logs" { + # fdio logs iam + source = "../" + name = "dynamic-aws-creds-vault-fdio-logs" +} + +module "fdio-docs" { + # fdio docs iam + source = "../" + name = "dynamic-aws-creds-vault-fdio-docs" +} + +module "fdio-csit-jenkins" { + # fdio csit jenkins iam + source = "../" + name = "dynamic-aws-creds-vault-fdio-csit-jenkins" +} diff --git a/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/providers.tf b/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/providers.tf new file mode 100644 index 0000000000..102fd31b87 --- /dev/null +++ b/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/providers.tf @@ -0,0 +1,5 @@ +provider "vault" { + address = var.vault_provider_address + skip_tls_verify = var.vault_provider_skip_tls_verify + token = var.vault_provider_token +}
\ No newline at end of file diff --git a/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/variables.tf b/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/variables.tf new file mode 100644 index 0000000000..d3d728a49d --- /dev/null +++ b/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/variables.tf @@ -0,0 +1,17 @@ +variable "vault_provider_address" { + description = "Vault cluster address." + type = string + default = "http://10.30.51.23:8200" +} + +variable "vault_provider_skip_tls_verify" { + description = "Verification of the Vault server's TLS certificate." + type = bool + default = false +} + +variable "vault_provider_token" { + description = "Vault root token." + type = string + sensitive = true +} diff --git a/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/versions.tf b/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/versions.tf new file mode 100644 index 0000000000..4c93000093 --- /dev/null +++ b/fdio.infra.terraform/terraform-vault-aws-secret-backend/fdio/versions.tf @@ -0,0 +1,13 @@ +terraform { + backend "consul" { + address = "10.30.51.23:8500" + scheme = "http" + path = "terraform/aws-secret-backend" + } + required_providers { + vault = { + version = ">= 3.12.0" + } + } + required_version = ">= 1.5.4" +} diff --git a/fdio.infra.terraform/terraform-vault-aws-secret-backend/main.tf b/fdio.infra.terraform/terraform-vault-aws-secret-backend/main.tf new file mode 100644 index 0000000000..a65c390792 --- /dev/null +++ b/fdio.infra.terraform/terraform-vault-aws-secret-backend/main.tf @@ -0,0 +1,37 @@ +resource "vault_aws_secret_backend" "aws" { + access_key = var.aws_access_key + secret_key = var.aws_secret_key + path = "${var.name}-path" + + default_lease_ttl_seconds = "0" + max_lease_ttl_seconds = "0" +} + +resource "vault_aws_secret_backend_role" "admin" { + backend = vault_aws_secret_backend.aws.path + name = "${var.name}-role" + credential_type = "iam_user" + + policy_document = <<EOF +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:*", "ec2:*" + ], + "Resource": "*" + } + ] +} +EOF +} + +output "backend" { + value = vault_aws_secret_backend.aws.path +} + +output "role" { + value = vault_aws_secret_backend_role.admin.name +} diff --git a/fdio.infra.terraform/terraform-vault-aws-secret-backend/variables.tf b/fdio.infra.terraform/terraform-vault-aws-secret-backend/variables.tf new file mode 100644 index 0000000000..2545345185 --- /dev/null +++ b/fdio.infra.terraform/terraform-vault-aws-secret-backend/variables.tf @@ -0,0 +1,17 @@ +variable "aws_access_key" { + description = "AWS access key" + type = string + sensitive = true +} + +variable "aws_secret_key" { + description = "AWS secret key" + type = string + sensitive = true +} + +variable "name" { + default = "dynamic-aws-creds-vault" + description = "Vault path" + type = string +} diff --git a/fdio.infra.terraform/terraform-vault-aws-secret-backend/versions.tf b/fdio.infra.terraform/terraform-vault-aws-secret-backend/versions.tf new file mode 100644 index 0000000000..996288568d --- /dev/null +++ b/fdio.infra.terraform/terraform-vault-aws-secret-backend/versions.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + vault = { + version = ">=2.22.1" + } + } + required_version = ">= 1.1.4" +} |