From c56316b0ad48ed198f07a8a6df2b5503a5012359 Mon Sep 17 00:00:00 2001 From: Yoshitaka Fujii <76274657+ystkfujii@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:02:22 +0900 Subject: [PATCH] Added terraform support for NIFCLOUD (#10227) * Add NIFCLOUD * Add tf-validate-nifcloud in gitlab-ci --- .gitlab-ci/terraform.yml | 6 + contrib/terraform/nifcloud/.gitignore | 5 + contrib/terraform/nifcloud/README.md | 137 ++++++++ .../terraform/nifcloud/generate-inventory.sh | 64 ++++ contrib/terraform/nifcloud/main.tf | 36 +++ .../modules/kubernetes-cluster/main.tf | 301 ++++++++++++++++++ .../modules/kubernetes-cluster/outputs.tf | 48 +++ .../templates/userdata.tftpl | 45 +++ .../modules/kubernetes-cluster/terraform.tf | 9 + .../modules/kubernetes-cluster/variables.tf | 81 +++++ contrib/terraform/nifcloud/output.tf | 3 + .../nifcloud/sample-inventory/cluster.tfvars | 22 ++ .../nifcloud/sample-inventory/group_vars | 1 + contrib/terraform/nifcloud/terraform.tf | 9 + contrib/terraform/nifcloud/variables.tf | 77 +++++ 15 files changed, 844 insertions(+) create mode 100644 contrib/terraform/nifcloud/.gitignore create mode 100644 contrib/terraform/nifcloud/README.md create mode 100755 contrib/terraform/nifcloud/generate-inventory.sh create mode 100644 contrib/terraform/nifcloud/main.tf create mode 100644 contrib/terraform/nifcloud/modules/kubernetes-cluster/main.tf create mode 100644 contrib/terraform/nifcloud/modules/kubernetes-cluster/outputs.tf create mode 100644 contrib/terraform/nifcloud/modules/kubernetes-cluster/templates/userdata.tftpl create mode 100644 contrib/terraform/nifcloud/modules/kubernetes-cluster/terraform.tf create mode 100644 contrib/terraform/nifcloud/modules/kubernetes-cluster/variables.tf create mode 100644 contrib/terraform/nifcloud/output.tf create mode 100644 contrib/terraform/nifcloud/sample-inventory/cluster.tfvars create mode 120000 contrib/terraform/nifcloud/sample-inventory/group_vars create mode 100644 contrib/terraform/nifcloud/terraform.tf create mode 100644 contrib/terraform/nifcloud/variables.tf diff --git a/.gitlab-ci/terraform.yml b/.gitlab-ci/terraform.yml index e72f2868de7..32991776c98 100644 --- a/.gitlab-ci/terraform.yml +++ b/.gitlab-ci/terraform.yml @@ -100,6 +100,12 @@ tf-validate-upcloud: PROVIDER: upcloud CLUSTER: $CI_COMMIT_REF_NAME +tf-validate-nifcloud: + extends: .terraform_validate + variables: + TF_VERSION: $TERRAFORM_VERSION + PROVIDER: nifcloud + # tf-packet-ubuntu20-default: # extends: .terraform_apply # variables: diff --git a/contrib/terraform/nifcloud/.gitignore b/contrib/terraform/nifcloud/.gitignore new file mode 100644 index 00000000000..9adadc30ac2 --- /dev/null +++ b/contrib/terraform/nifcloud/.gitignore @@ -0,0 +1,5 @@ +*.tfstate* +.terraform.lock.hcl +.terraform + +sample-inventory/inventory.ini diff --git a/contrib/terraform/nifcloud/README.md b/contrib/terraform/nifcloud/README.md new file mode 100644 index 00000000000..8c46df402f5 --- /dev/null +++ b/contrib/terraform/nifcloud/README.md @@ -0,0 +1,137 @@ +# Kubernetes on NIFCLOUD with Terraform + +Provision a Kubernetes cluster on [NIFCLOUD](https://pfs.nifcloud.com/) using Terraform and Kubespray + +## Overview + +The setup looks like following + +```text + Kubernetes cluster + +----------------------------+ ++---------------+ | +--------------------+ | +| | | | +--------------------+ | +| API server LB +---------> | | | | +| | | | | Control Plane/etcd | | ++---------------+ | | | node(s) | | + | +-+ | | + | +--------------------+ | + | ^ | + | | | + | v | + | +--------------------+ | + | | +--------------------+ | + | | | | | + | | | Worker | | + | | | node(s) | | + | +-+ | | + | +--------------------+ | + +----------------------------+ +``` + +## Requirements + +* Terraform 1.3.7 + +## Quickstart + +### Export Variables + +* Your NIFCLOUD credentials: + + ```bash + export NIFCLOUD_ACCESS_KEY_ID= + export NIFCLOUD_SECRET_ACCESS_KEY= + ``` + +* The SSH KEY used to connect to the instance: + * FYI: [Cloud Help(SSH Key)](https://pfs.nifcloud.com/help/ssh.htm) + + ```bash + export TF_VAR_SSHKEY_NAME= + ``` + +* The IP address to connect to bastion server: + + ```bash + export TF_VAR_working_instance_ip=$(curl ifconfig.me) + ``` + +### Create The Infrastructure + +* Run terraform: + + ```bash + terraform init + terraform apply -var-file ./sample-inventory/cluster.tfvars + ``` + +### Setup The Kubernetes + +* Generate cluster configuration file: + + ```bash + ./generate-inventory.sh > sample-inventory/inventory.ini + +* Export Variables: + + ```bash + BASTION_IP=$(terraform output -json | jq -r '.kubernetes_cluster.value.bastion_info | to_entries[].value.public_ip') + API_LB_IP=$(terraform output -json | jq -r '.kubernetes_cluster.value.control_plane_lb') + CP01_IP=$(terraform output -json | jq -r '.kubernetes_cluster.value.control_plane_info | to_entries[0].value.private_ip') + export ANSIBLE_SSH_ARGS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ProxyCommand=\"ssh root@${BASTION_IP} -W %h:%p\"" + ``` + +* Set ssh-agent" + + ```bash + eval `ssh-agent` + ssh-add + ``` + +* Run cluster.yml playbook: + + ```bash + cd ./../../../ + ansible-playbook -i contrib/terraform/nifcloud/inventory/inventory.ini cluster.yml + ``` + +### Connecting to Kubernetes + +* [Install kubectl](https://kubernetes.io/docs/tasks/tools/) on the localhost +* Fetching kubeconfig file: + + ```bash + mkdir -p ~/.kube + scp -o ProxyCommand="ssh root@${BASTION_IP} -W %h:%p" root@${CP01_IP}:/etc/kubernetes/admin.conf ~/.kube/config + ``` + +* Rewrite /etc/hosts + + ```bash + sudo echo "${API_LB_IP} lb-apiserver.kubernetes.local" >> /etc/hosts + ``` + +* Run kubectl + + ```bash + kubectl get node + ``` + +## Variables + +* `region`: Region where to run the cluster +* `az`: Availability zone where to run the cluster +* `private_ip_bn`: Private ip address of bastion server +* `private_network_cidr`: Subnet of private network +* `instances_cp`: Machine to provision as Control Plane. Key of this object will be used as part of the machine' name + * `private_ip`: private ip address of machine +* `instances_wk`: Machine to provision as Worker Node. Key of this object will be used as part of the machine' name + * `private_ip`: private ip address of machine +* `instance_key_name`: The key name of the Key Pair to use for the instance +* `instance_type_bn`: The instance type of bastion server +* `instance_type_wk`: The instance type of worker node +* `instance_type_cp`: The instance type of control plane +* `image_name`: OS image used for the instance +* `working_instance_ip`: The IP address to connect to bastion server +* `accounting_type`: Accounting type. (1: monthly, 2: pay per use) diff --git a/contrib/terraform/nifcloud/generate-inventory.sh b/contrib/terraform/nifcloud/generate-inventory.sh new file mode 100755 index 00000000000..5d90eb5f426 --- /dev/null +++ b/contrib/terraform/nifcloud/generate-inventory.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# +# Generates a inventory file based on the terraform output. +# After provisioning a cluster, simply run this command and supply the terraform state file +# Default state file is terraform.tfstate +# + +set -e + +TF_OUT=$(terraform output -json) + +CONTROL_PLANES=$(jq -r '.kubernetes_cluster.value.control_plane_info | to_entries[]' <(echo "${TF_OUT}")) +WORKERS=$(jq -r '.kubernetes_cluster.value.worker_info | to_entries[]' <(echo "${TF_OUT}")) +mapfile -t CONTROL_PLANE_NAMES < <(jq -r '.key' <(echo "${CONTROL_PLANES}")) +mapfile -t WORKER_NAMES < <(jq -r '.key' <(echo "${WORKERS}")) + +API_LB=$(jq -r '.kubernetes_cluster.value.control_plane_lb' <(echo "${TF_OUT}")) + +echo "[all]" +# Generate control plane hosts +i=1 +for name in "${CONTROL_PLANE_NAMES[@]}"; do + private_ip=$(jq -r '. | select( .key=='"\"${name}\""' ) | .value.private_ip' <(echo "${CONTROL_PLANES}")) + echo "${name} ansible_user=root ansible_host=${private_ip} access_ip=${private_ip} ip=${private_ip} etcd_member_name=etcd${i}" + i=$(( i + 1 )) +done + +# Generate worker hosts +for name in "${WORKER_NAMES[@]}"; do + private_ip=$(jq -r '. | select( .key=='"\"${name}\""' ) | .value.private_ip' <(echo "${WORKERS}")) + echo "${name} ansible_user=root ansible_host=${private_ip} access_ip=${private_ip} ip=${private_ip}" +done + +API_LB=$(jq -r '.kubernetes_cluster.value.control_plane_lb' <(echo "${TF_OUT}")) + +echo "" +echo "[all:vars]" +echo "upstream_dns_servers=['8.8.8.8','8.8.4.4']" +echo "loadbalancer_apiserver={'address':'${API_LB}','port':'6443'}" + + +echo "" +echo "[kube_control_plane]" +for name in "${CONTROL_PLANE_NAMES[@]}"; do + echo "${name}" +done + +echo "" +echo "[etcd]" +for name in "${CONTROL_PLANE_NAMES[@]}"; do + echo "${name}" +done + +echo "" +echo "[kube_node]" +for name in "${WORKER_NAMES[@]}"; do + echo "${name}" +done + +echo "" +echo "[k8s_cluster:children]" +echo "kube_control_plane" +echo "kube_node" diff --git a/contrib/terraform/nifcloud/main.tf b/contrib/terraform/nifcloud/main.tf new file mode 100644 index 00000000000..d5a070967bc --- /dev/null +++ b/contrib/terraform/nifcloud/main.tf @@ -0,0 +1,36 @@ +provider "nifcloud" { + region = var.region +} + +module "kubernetes_cluster" { + source = "./modules/kubernetes-cluster" + + availability_zone = var.az + prefix = "dev" + + private_network_cidr = var.private_network_cidr + + instance_key_name = var.instance_key_name + instances_cp = var.instances_cp + instances_wk = var.instances_wk + image_name = var.image_name + + instance_type_bn = var.instance_type_bn + instance_type_cp = var.instance_type_cp + instance_type_wk = var.instance_type_wk + + private_ip_bn = var.private_ip_bn + + additional_lb_filter = [var.working_instance_ip] +} + +resource "nifcloud_security_group_rule" "ssh_from_bastion" { + security_group_names = [ + module.kubernetes_cluster.security_group_name.bastion + ] + type = "IN" + from_port = 22 + to_port = 22 + protocol = "TCP" + cidr_ip = var.working_instance_ip +} diff --git a/contrib/terraform/nifcloud/modules/kubernetes-cluster/main.tf b/contrib/terraform/nifcloud/modules/kubernetes-cluster/main.tf new file mode 100644 index 00000000000..0e5fd383da9 --- /dev/null +++ b/contrib/terraform/nifcloud/modules/kubernetes-cluster/main.tf @@ -0,0 +1,301 @@ +################################################# +## +## Local variables +## +locals { + # e.g. east-11 is 11 + az_num = reverse(split("-", var.availability_zone))[0] + # e.g. east-11 is e11 + az_short_name = "${substr(reverse(split("-", var.availability_zone))[1], 0, 1)}${local.az_num}" + + # Port used by the protocol + port_ssh = 22 + port_kubectl = 6443 + port_kubelet = 10250 + + # calico: https://docs.tigera.io/calico/latest/getting-started/kubernetes/requirements#network-requirements + port_bgp = 179 + port_vxlan = 4789 + port_etcd = 2379 +} + +################################################# +## +## General +## + +# data +data "nifcloud_image" "this" { + image_name = var.image_name +} + +# private lan +resource "nifcloud_private_lan" "this" { + private_lan_name = "${var.prefix}lan" + availability_zone = var.availability_zone + cidr_block = var.private_network_cidr + accounting_type = var.accounting_type +} + +################################################# +## +## Bastion +## +resource "nifcloud_security_group" "bn" { + group_name = "${var.prefix}bn" + description = "${var.prefix} bastion" + availability_zone = var.availability_zone +} + +resource "nifcloud_instance" "bn" { + + instance_id = "${local.az_short_name}${var.prefix}bn01" + security_group = nifcloud_security_group.bn.group_name + instance_type = var.instance_type_bn + + user_data = templatefile("${path.module}/templates/userdata.tftpl", { + private_ip_address = var.private_ip_bn + ssh_port = local.port_ssh + hostname = "${local.az_short_name}${var.prefix}bn01" + }) + + availability_zone = var.availability_zone + accounting_type = var.accounting_type + image_id = data.nifcloud_image.this.image_id + key_name = var.instance_key_name + + network_interface { + network_id = "net-COMMON_GLOBAL" + } + network_interface { + network_id = nifcloud_private_lan.this.network_id + ip_address = "static" + } + + # The image_id changes when the OS image type is demoted from standard to public. + lifecycle { + ignore_changes = [ + image_id, + user_data, + ] + } +} + +################################################# +## +## Control Plane +## +resource "nifcloud_security_group" "cp" { + group_name = "${var.prefix}cp" + description = "${var.prefix} control plane" + availability_zone = var.availability_zone +} + +resource "nifcloud_instance" "cp" { + for_each = var.instances_cp + + instance_id = "${local.az_short_name}${var.prefix}${each.key}" + security_group = nifcloud_security_group.cp.group_name + instance_type = var.instance_type_cp + user_data = templatefile("${path.module}/templates/userdata.tftpl", { + private_ip_address = each.value.private_ip + ssh_port = local.port_ssh + hostname = "${local.az_short_name}${var.prefix}${each.key}" + }) + + availability_zone = var.availability_zone + accounting_type = var.accounting_type + image_id = data.nifcloud_image.this.image_id + key_name = var.instance_key_name + + network_interface { + network_id = "net-COMMON_GLOBAL" + } + network_interface { + network_id = nifcloud_private_lan.this.network_id + ip_address = "static" + } + + # The image_id changes when the OS image type is demoted from standard to public. + lifecycle { + ignore_changes = [ + image_id, + user_data, + ] + } +} + +resource "nifcloud_load_balancer" "this" { + load_balancer_name = "${local.az_short_name}${var.prefix}cp" + accounting_type = var.accounting_type + balancing_type = 1 // Round-Robin + load_balancer_port = local.port_kubectl + instance_port = local.port_kubectl + instances = [for v in nifcloud_instance.cp : v.instance_id] + filter = concat( + [for k, v in nifcloud_instance.cp : v.public_ip], + [for k, v in nifcloud_instance.wk : v.public_ip], + var.additional_lb_filter, + ) + filter_type = 1 // Allow +} + +################################################# +## +## Worker +## +resource "nifcloud_security_group" "wk" { + group_name = "${var.prefix}wk" + description = "${var.prefix} worker" + availability_zone = var.availability_zone +} + +resource "nifcloud_instance" "wk" { + for_each = var.instances_wk + + instance_id = "${local.az_short_name}${var.prefix}${each.key}" + security_group = nifcloud_security_group.wk.group_name + instance_type = var.instance_type_wk + user_data = templatefile("${path.module}/templates/userdata.tftpl", { + private_ip_address = each.value.private_ip + ssh_port = local.port_ssh + hostname = "${local.az_short_name}${var.prefix}${each.key}" + }) + + availability_zone = var.availability_zone + accounting_type = var.accounting_type + image_id = data.nifcloud_image.this.image_id + key_name = var.instance_key_name + + network_interface { + network_id = "net-COMMON_GLOBAL" + } + network_interface { + network_id = nifcloud_private_lan.this.network_id + ip_address = "static" + } + + # The image_id changes when the OS image type is demoted from standard to public. + lifecycle { + ignore_changes = [ + image_id, + user_data, + ] + } +} + +################################################# +## +## Security Group Rule: Kubernetes +## + +# ssh +resource "nifcloud_security_group_rule" "ssh_from_bastion" { + security_group_names = [ + nifcloud_security_group.wk.group_name, + nifcloud_security_group.cp.group_name, + ] + type = "IN" + from_port = local.port_ssh + to_port = local.port_ssh + protocol = "TCP" + source_security_group_name = nifcloud_security_group.bn.group_name +} + +# kubectl +resource "nifcloud_security_group_rule" "kubectl_from_worker" { + security_group_names = [ + nifcloud_security_group.cp.group_name, + ] + type = "IN" + from_port = local.port_kubectl + to_port = local.port_kubectl + protocol = "TCP" + source_security_group_name = nifcloud_security_group.wk.group_name +} + +# kubelet +resource "nifcloud_security_group_rule" "kubelet_from_worker" { + security_group_names = [ + nifcloud_security_group.cp.group_name, + ] + type = "IN" + from_port = local.port_kubelet + to_port = local.port_kubelet + protocol = "TCP" + source_security_group_name = nifcloud_security_group.wk.group_name +} + +resource "nifcloud_security_group_rule" "kubelet_from_control_plane" { + security_group_names = [ + nifcloud_security_group.wk.group_name, + ] + type = "IN" + from_port = local.port_kubelet + to_port = local.port_kubelet + protocol = "TCP" + source_security_group_name = nifcloud_security_group.cp.group_name +} + +################################################# +## +## Security Group Rule: calico +## + +# vslan +resource "nifcloud_security_group_rule" "vxlan_from_control_plane" { + security_group_names = [ + nifcloud_security_group.wk.group_name, + ] + type = "IN" + from_port = local.port_vxlan + to_port = local.port_vxlan + protocol = "UDP" + source_security_group_name = nifcloud_security_group.cp.group_name +} + +resource "nifcloud_security_group_rule" "vxlan_from_worker" { + security_group_names = [ + nifcloud_security_group.cp.group_name, + ] + type = "IN" + from_port = local.port_vxlan + to_port = local.port_vxlan + protocol = "UDP" + source_security_group_name = nifcloud_security_group.wk.group_name +} + +# bgp +resource "nifcloud_security_group_rule" "bgp_from_control_plane" { + security_group_names = [ + nifcloud_security_group.wk.group_name, + ] + type = "IN" + from_port = local.port_bgp + to_port = local.port_bgp + protocol = "TCP" + source_security_group_name = nifcloud_security_group.cp.group_name +} + +resource "nifcloud_security_group_rule" "bgp_from_worker" { + security_group_names = [ + nifcloud_security_group.cp.group_name, + ] + type = "IN" + from_port = local.port_bgp + to_port = local.port_bgp + protocol = "TCP" + source_security_group_name = nifcloud_security_group.wk.group_name +} + +# etcd +resource "nifcloud_security_group_rule" "etcd_from_worker" { + security_group_names = [ + nifcloud_security_group.cp.group_name, + ] + type = "IN" + from_port = local.port_etcd + to_port = local.port_etcd + protocol = "TCP" + source_security_group_name = nifcloud_security_group.wk.group_name +} diff --git a/contrib/terraform/nifcloud/modules/kubernetes-cluster/outputs.tf b/contrib/terraform/nifcloud/modules/kubernetes-cluster/outputs.tf new file mode 100644 index 00000000000..a6232f821da --- /dev/null +++ b/contrib/terraform/nifcloud/modules/kubernetes-cluster/outputs.tf @@ -0,0 +1,48 @@ +output "control_plane_lb" { + description = "The DNS name of LB for control plane" + value = nifcloud_load_balancer.this.dns_name +} + +output "security_group_name" { + description = "The security group used in the cluster" + value = { + bastion = nifcloud_security_group.bn.group_name, + control_plane = nifcloud_security_group.cp.group_name, + worker = nifcloud_security_group.wk.group_name, + } +} + +output "private_network_id" { + description = "The private network used in the cluster" + value = nifcloud_private_lan.this.id +} + +output "bastion_info" { + description = "The basion information in cluster" + value = { (nifcloud_instance.bn.instance_id) : { + instance_id = nifcloud_instance.bn.instance_id, + unique_id = nifcloud_instance.bn.unique_id, + private_ip = nifcloud_instance.bn.private_ip, + public_ip = nifcloud_instance.bn.public_ip, + } } +} + +output "worker_info" { + description = "The worker information in cluster" + value = { for v in nifcloud_instance.wk : v.instance_id => { + instance_id = v.instance_id, + unique_id = v.unique_id, + private_ip = v.private_ip, + public_ip = v.public_ip, + } } +} + +output "control_plane_info" { + description = "The control plane information in cluster" + value = { for v in nifcloud_instance.cp : v.instance_id => { + instance_id = v.instance_id, + unique_id = v.unique_id, + private_ip = v.private_ip, + public_ip = v.public_ip, + } } +} diff --git a/contrib/terraform/nifcloud/modules/kubernetes-cluster/templates/userdata.tftpl b/contrib/terraform/nifcloud/modules/kubernetes-cluster/templates/userdata.tftpl new file mode 100644 index 00000000000..55e626a2a0f --- /dev/null +++ b/contrib/terraform/nifcloud/modules/kubernetes-cluster/templates/userdata.tftpl @@ -0,0 +1,45 @@ +#!/bin/bash + +################################################# +## +## IP Address +## +configure_private_ip_address () { + cat << EOS > /etc/netplan/01-netcfg.yaml +network: + version: 2 + renderer: networkd + ethernets: + ens192: + dhcp4: yes + dhcp6: yes + dhcp-identifier: mac + ens224: + dhcp4: no + dhcp6: no + addresses: [${private_ip_address}] +EOS + netplan apply +} +configure_private_ip_address + +################################################# +## +## SSH +## +configure_ssh_port () { + sed -i 's/^#*Port [0-9]*/Port ${ssh_port}/' /etc/ssh/sshd_config +} +configure_ssh_port + +################################################# +## +## Hostname +## +hostnamectl set-hostname ${hostname} + +################################################# +## +## Disable swap files genereated by systemd-gpt-auto-generator +## +systemctl mask "dev-sda3.swap" diff --git a/contrib/terraform/nifcloud/modules/kubernetes-cluster/terraform.tf b/contrib/terraform/nifcloud/modules/kubernetes-cluster/terraform.tf new file mode 100644 index 00000000000..97ef4847bf2 --- /dev/null +++ b/contrib/terraform/nifcloud/modules/kubernetes-cluster/terraform.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">=1.3.7" + required_providers { + nifcloud = { + source = "nifcloud/nifcloud" + version = ">= 1.8.0, < 2.0.0" + } + } +} diff --git a/contrib/terraform/nifcloud/modules/kubernetes-cluster/variables.tf b/contrib/terraform/nifcloud/modules/kubernetes-cluster/variables.tf new file mode 100644 index 00000000000..65c11fe2029 --- /dev/null +++ b/contrib/terraform/nifcloud/modules/kubernetes-cluster/variables.tf @@ -0,0 +1,81 @@ +variable "availability_zone" { + description = "The availability zone" + type = string +} + +variable "prefix" { + description = "The prefix for the entire cluster" + type = string + validation { + condition = length(var.prefix) <= 5 + error_message = "Must be a less than 5 character long." + } +} + +variable "private_network_cidr" { + description = "The subnet of private network" + type = string + validation { + condition = can(cidrnetmask(var.private_network_cidr)) + error_message = "Must be a valid IPv4 CIDR block address." + } +} + +variable "private_ip_bn" { + description = "Private IP of bastion server" + type = string +} + +variable "instances_cp" { + type = map(object({ + private_ip = string + })) +} + +variable "instances_wk" { + type = map(object({ + private_ip = string + })) +} + +variable "instance_key_name" { + description = "The key name of the Key Pair to use for the instance" + type = string +} + +variable "instance_type_bn" { + description = "The instance type of bastion server" + type = string +} + +variable "instance_type_wk" { + description = "The instance type of worker" + type = string +} + +variable "instance_type_cp" { + description = "The instance type of control plane" + type = string +} + +variable "image_name" { + description = "The name of image" + type = string +} + +variable "additional_lb_filter" { + description = "Additional LB filter" + type = list(string) +} + +variable "accounting_type" { + type = string + default = "1" + validation { + condition = anytrue([ + var.accounting_type == "1", // Monthly + var.accounting_type == "2", // Pay per use + ]) + error_message = "Must be a 1 or 2." + } +} diff --git a/contrib/terraform/nifcloud/output.tf b/contrib/terraform/nifcloud/output.tf new file mode 100644 index 00000000000..dcdeacba2c8 --- /dev/null +++ b/contrib/terraform/nifcloud/output.tf @@ -0,0 +1,3 @@ +output "kubernetes_cluster" { + value = module.kubernetes_cluster +} diff --git a/contrib/terraform/nifcloud/sample-inventory/cluster.tfvars b/contrib/terraform/nifcloud/sample-inventory/cluster.tfvars new file mode 100644 index 00000000000..3410a54a886 --- /dev/null +++ b/contrib/terraform/nifcloud/sample-inventory/cluster.tfvars @@ -0,0 +1,22 @@ +region = "jp-west-1" +az = "west-11" + +instance_key_name = "deployerkey" + +instance_type_bn = "e-medium" +instance_type_cp = "e-medium" +instance_type_wk = "e-medium" + +private_network_cidr = "192.168.30.0/24" +instances_cp = { + "cp01" : { private_ip : "192.168.30.11/24" } + "cp02" : { private_ip : "192.168.30.12/24" } + "cp03" : { private_ip : "192.168.30.13/24" } +} +instances_wk = { + "wk01" : { private_ip : "192.168.30.21/24" } + "wk02" : { private_ip : "192.168.30.22/24" } +} +private_ip_bn = "192.168.30.10/24" + +image_name = "Ubuntu Server 22.04 LTS" diff --git a/contrib/terraform/nifcloud/sample-inventory/group_vars b/contrib/terraform/nifcloud/sample-inventory/group_vars new file mode 120000 index 00000000000..37359582379 --- /dev/null +++ b/contrib/terraform/nifcloud/sample-inventory/group_vars @@ -0,0 +1 @@ +../../../../inventory/sample/group_vars \ No newline at end of file diff --git a/contrib/terraform/nifcloud/terraform.tf b/contrib/terraform/nifcloud/terraform.tf new file mode 100644 index 00000000000..9a14bc665af --- /dev/null +++ b/contrib/terraform/nifcloud/terraform.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">=1.3.7" + required_providers { + nifcloud = { + source = "nifcloud/nifcloud" + version = "1.8.0" + } + } +} diff --git a/contrib/terraform/nifcloud/variables.tf b/contrib/terraform/nifcloud/variables.tf new file mode 100644 index 00000000000..558655ffe8a --- /dev/null +++ b/contrib/terraform/nifcloud/variables.tf @@ -0,0 +1,77 @@ +variable "region" { + description = "The region" + type = string +} + +variable "az" { + description = "The availability zone" + type = string +} + +variable "private_ip_bn" { + description = "Private IP of bastion server" + type = string +} + +variable "private_network_cidr" { + description = "The subnet of private network" + type = string + validation { + condition = can(cidrnetmask(var.private_network_cidr)) + error_message = "Must be a valid IPv4 CIDR block address." + } +} + +variable "instances_cp" { + type = map(object({ + private_ip = string + })) +} + +variable "instances_wk" { + type = map(object({ + private_ip = string + })) +} + +variable "instance_key_name" { + description = "The key name of the Key Pair to use for the instance" + type = string +} + +variable "instance_type_bn" { + description = "The instance type of bastion server" + type = string +} + +variable "instance_type_wk" { + description = "The instance type of worker" + type = string +} + +variable "instance_type_cp" { + description = "The instance type of control plane" + type = string +} + +variable "image_name" { + description = "The name of image" + type = string +} + +variable "working_instance_ip" { + description = "The IP address to connect to bastion server." + type = string +} + +variable "accounting_type" { + type = string + default = "2" + validation { + condition = anytrue([ + var.accounting_type == "1", // Monthly + var.accounting_type == "2", // Pay per use + ]) + error_message = "Must be a 1 or 2." + } +}