Merge pull request #2033 from ArchiFleKs/terraform-fix-cred
Update Terraform docs and authentication method
This commit is contained in:
commit
bfe196236f
12 changed files with 485 additions and 393 deletions
4
contrib/terraform/openstack/.gitignore
vendored
Normal file
4
contrib/terraform/openstack/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
.terraform
|
||||
*.tfvars
|
||||
*.tfstate
|
||||
*.tfstate.backup
|
|
@ -82,23 +82,102 @@ used to deploy and provision the software requirements.
|
|||
|
||||
#### OpenStack
|
||||
|
||||
Ensure your OpenStack **Identity v2** credentials are loaded in environment
|
||||
variables. This can be done by downloading a credentials .rc file from your
|
||||
OpenStack dashboard and sourcing it:
|
||||
No provider variables are hard coded inside `variables.tf` because Terraform
|
||||
supports various authentication method for OpenStack, between identity v2 and
|
||||
v3 API, `openrc` or `clouds.yaml`.
|
||||
|
||||
These are examples and may vary depending on your OpenStack cloud provider,
|
||||
for an exhaustive list on how to authenticate on OpenStack with Terraform
|
||||
please read the [OpenStack provider documentation](https://www.terraform.io/docs/providers/openstack/).
|
||||
|
||||
##### Recommended method : clouds.yaml
|
||||
|
||||
Newer recommended authentication method is to use a `clouds.yaml` file that can be store in :
|
||||
|
||||
* `Current Directory`
|
||||
* `~/.config/openstack`
|
||||
* `/etc/openstack`
|
||||
|
||||
`clouds.yaml` :
|
||||
|
||||
```
|
||||
$ source ~/.stackrc
|
||||
clouds:
|
||||
mycloud:
|
||||
auth:
|
||||
auth_url: https://openstack:5000/v3
|
||||
username: "username"
|
||||
project_name: "projectname"
|
||||
project_id: projectid
|
||||
user_domain_name: "Default"
|
||||
password: "password"
|
||||
region_name: "RegionOne"
|
||||
interface: "public"
|
||||
identity_api_version: 3
|
||||
```
|
||||
|
||||
Ensure that you have your Openstack credentials loaded into Terraform
|
||||
environment variables. Likely via a command similar to:
|
||||
If you have multiple clouds defined in your `clouds.yaml` file you can choose
|
||||
the one you want to use with the environment variable `OS_CLOUD` :
|
||||
|
||||
```
|
||||
$ echo Setting up Terraform creds && \
|
||||
export TF_VAR_username=${OS_USERNAME} && \
|
||||
export TF_VAR_password=${OS_PASSWORD} && \
|
||||
export TF_VAR_tenant=${OS_TENANT_NAME} && \
|
||||
export TF_VAR_auth_url=${OS_AUTH_URL}
|
||||
export OS_CLOUD=mycloud
|
||||
```
|
||||
|
||||
##### Deprecated method : openrc
|
||||
|
||||
When using classic environment variables, Terraform uses default `OS_*`
|
||||
environment variables :
|
||||
|
||||
With identity v2 :
|
||||
|
||||
```
|
||||
source openrc
|
||||
|
||||
env | grep OS
|
||||
|
||||
OS_AUTH_URL=https://openstack:5000/v2.0
|
||||
OS_PROJECT_ID=projectid
|
||||
OS_PROJECT_NAME=projectname
|
||||
OS_USERNAME=username
|
||||
OS_PASSWORD=password
|
||||
OS_REGION_NAME=RegionOne
|
||||
OS_INTERFACE=public
|
||||
OS_IDENTITY_API_VERSION=2
|
||||
```
|
||||
|
||||
With identity v3 :
|
||||
|
||||
```
|
||||
source openrc
|
||||
|
||||
env | grep OS
|
||||
|
||||
OS_AUTH_URL=https://openstack:5000/v3
|
||||
OS_PROJECT_ID=projectid
|
||||
OS_PROJECT_NAME=username
|
||||
OS_PROJECT_DOMAIN_ID=default
|
||||
OS_USERNAME=username
|
||||
OS_PASSWORD=password
|
||||
OS_REGION_NAME=RegionOne
|
||||
OS_INTERFACE=public
|
||||
OS_IDENTITY_API_VERSION=3
|
||||
OS_USER_DOMAIN_NAME=Default
|
||||
```
|
||||
|
||||
Terraform does not support a mix of DomainName and DomainID, choose one or the
|
||||
other :
|
||||
|
||||
```
|
||||
* provider.openstack: You must provide exactly one of DomainID or DomainName to authenticate by Username
|
||||
```
|
||||
|
||||
```
|
||||
unset OS_USER_DOMAIN_NAME
|
||||
export OS_USER_DOMAIN_ID=default
|
||||
|
||||
or
|
||||
|
||||
unset OS_PROJECT_DOMAIN_ID
|
||||
set OS_PROJECT_DOMAIN_NAME=Default
|
||||
```
|
||||
|
||||
### Terraform Variables
|
||||
|
@ -114,7 +193,7 @@ ones:
|
|||
|---------|-------------|
|
||||
|`cluster_name` | All OpenStack resources will use the Terraform variable`cluster_name` (default`example`) in their name to make it easier to track. For example the first compute resource will be named`example-kubernetes-1`. |
|
||||
|`network_name` | The name to be given to the internal network that will be generated |
|
||||
|`dns_nameservers`| An array of DNS name server names to be used by hosts in the internal subnet. |
|
||||
|`dns_nameservers`| An array of DNS name server names to be used by hosts in the internal subnet. |
|
||||
|`floatingip_pool` | Name of the pool from which floating IPs will be allocated |
|
||||
|`external_net` | UUID of the external network that will be routed to |
|
||||
|`flavor_k8s_master`,`flavor_k8s_node`,`flavor_etcd`, `flavor_bastion`,`flavor_gfs_node` | Flavor depends on your openstack installation, you can get available flavor IDs through`nova flavor-list` |
|
||||
|
@ -129,7 +208,21 @@ ones:
|
|||
|`number_of_gfs_nodes_no_floating_ip` | Number of gluster servers to provision. |
|
||||
| `gfs_volume_size_in_gb` | Size of the non-ephemeral volumes to be attached to store the GlusterFS bricks |
|
||||
|
||||
### Terraform files
|
||||
|
||||
In the root folder, the following files might be created (either by Terraform
|
||||
or manually), to prevent you from pushing them accidentally they are in a
|
||||
`.gitignore` file in the `terraform/openstack` directory :
|
||||
|
||||
* `.terraform`
|
||||
* `.tfvars`
|
||||
* `.tfstate`
|
||||
* `.tfstate.backup`
|
||||
|
||||
You can still add them manually if you want to.
|
||||
|
||||
## Initializing Terraform
|
||||
|
||||
Before Terraform can operate on your cluster you need to install required
|
||||
plugins. This is accomplished with the command
|
||||
|
||||
|
@ -163,6 +256,12 @@ $ terraform destroy -state=contrib/terraform/openstack/terraform.tfstate -var-fi
|
|||
You can enable debugging output from Terraform by setting
|
||||
`OS_DEBUG` to 1 and`TF_LOG` to`DEBUG` before runing the terraform command
|
||||
|
||||
## Terraform output
|
||||
|
||||
Terraform can output useful values that need to be reused if you want to use Kubernetes OpenStack cloud provider with Neutron/Octavia LBaaS or Cinder persistent Volume provisioning:
|
||||
|
||||
- `private_subnet_id`: the subnet where your instances are running, maps to `openstack_lbaas_subnet_id`
|
||||
- `floating_network_id`: the network_id where the floating IP are provisioned, maps to `openstack_lbaas_floating_network_id`
|
||||
|
||||
# Running the Ansible Script
|
||||
Ensure your local ssh-agent is running and your ssh key has been added. This
|
||||
|
|
|
@ -1,55 +1,77 @@
|
|||
|
||||
module "network" {
|
||||
source = "modules/network"
|
||||
|
||||
external_net = "${var.external_net}"
|
||||
network_name = "${var.network_name}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
external_net = "${var.external_net}"
|
||||
network_name = "${var.network_name}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
dns_nameservers = "${var.dns_nameservers}"
|
||||
}
|
||||
|
||||
|
||||
module "ips" {
|
||||
source = "modules/ips"
|
||||
|
||||
number_of_k8s_masters = "${var.number_of_k8s_masters}"
|
||||
number_of_k8s_masters = "${var.number_of_k8s_masters}"
|
||||
number_of_k8s_masters_no_etcd = "${var.number_of_k8s_masters_no_etcd}"
|
||||
number_of_k8s_nodes = "${var.number_of_k8s_nodes}"
|
||||
floatingip_pool = "${var.floatingip_pool}"
|
||||
number_of_bastions = "${var.number_of_bastions}"
|
||||
external_net = "${var.external_net}"
|
||||
network_name = "${var.network_name}"
|
||||
router_id = "${module.network.router_id}"
|
||||
number_of_k8s_nodes = "${var.number_of_k8s_nodes}"
|
||||
floatingip_pool = "${var.floatingip_pool}"
|
||||
number_of_bastions = "${var.number_of_bastions}"
|
||||
external_net = "${var.external_net}"
|
||||
network_name = "${var.network_name}"
|
||||
router_id = "${module.network.router_id}"
|
||||
}
|
||||
|
||||
module "compute" {
|
||||
source = "modules/compute"
|
||||
|
||||
cluster_name = "${var.cluster_name}"
|
||||
number_of_k8s_masters = "${var.number_of_k8s_masters}"
|
||||
number_of_k8s_masters_no_etcd = "${var.number_of_k8s_masters_no_etcd}"
|
||||
number_of_etcd = "${var.number_of_etcd}"
|
||||
number_of_k8s_masters_no_floating_ip = "${var.number_of_k8s_masters_no_floating_ip}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
number_of_k8s_masters = "${var.number_of_k8s_masters}"
|
||||
number_of_k8s_masters_no_etcd = "${var.number_of_k8s_masters_no_etcd}"
|
||||
number_of_etcd = "${var.number_of_etcd}"
|
||||
number_of_k8s_masters_no_floating_ip = "${var.number_of_k8s_masters_no_floating_ip}"
|
||||
number_of_k8s_masters_no_floating_ip_no_etcd = "${var.number_of_k8s_masters_no_floating_ip_no_etcd}"
|
||||
number_of_k8s_nodes = "${var.number_of_k8s_nodes}"
|
||||
number_of_bastions = "${var.number_of_bastions}"
|
||||
number_of_k8s_nodes_no_floating_ip = "${var.number_of_k8s_nodes_no_floating_ip}"
|
||||
number_of_gfs_nodes_no_floating_ip = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
gfs_volume_size_in_gb = "${var.gfs_volume_size_in_gb}"
|
||||
public_key_path = "${var.public_key_path}"
|
||||
image = "${var.image}"
|
||||
image_gfs = "${var.image_gfs}"
|
||||
ssh_user = "${var.ssh_user}"
|
||||
ssh_user_gfs = "${var.ssh_user_gfs}"
|
||||
flavor_k8s_master = "${var.flavor_k8s_master}"
|
||||
flavor_k8s_node = "${var.flavor_k8s_node}"
|
||||
flavor_etcd = "${var.flavor_etcd}"
|
||||
flavor_gfs_node = "${var.flavor_gfs_node}"
|
||||
network_name = "${var.network_name}"
|
||||
flavor_bastion = "${var.flavor_bastion}"
|
||||
k8s_master_fips = "${module.ips.k8s_master_fips}"
|
||||
k8s_node_fips = "${module.ips.k8s_node_fips}"
|
||||
bastion_fips = "${module.ips.bastion_fips}"
|
||||
number_of_k8s_nodes = "${var.number_of_k8s_nodes}"
|
||||
number_of_bastions = "${var.number_of_bastions}"
|
||||
number_of_k8s_nodes_no_floating_ip = "${var.number_of_k8s_nodes_no_floating_ip}"
|
||||
number_of_gfs_nodes_no_floating_ip = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
gfs_volume_size_in_gb = "${var.gfs_volume_size_in_gb}"
|
||||
public_key_path = "${var.public_key_path}"
|
||||
image = "${var.image}"
|
||||
image_gfs = "${var.image_gfs}"
|
||||
ssh_user = "${var.ssh_user}"
|
||||
ssh_user_gfs = "${var.ssh_user_gfs}"
|
||||
flavor_k8s_master = "${var.flavor_k8s_master}"
|
||||
flavor_k8s_node = "${var.flavor_k8s_node}"
|
||||
flavor_etcd = "${var.flavor_etcd}"
|
||||
flavor_gfs_node = "${var.flavor_gfs_node}"
|
||||
network_name = "${var.network_name}"
|
||||
flavor_bastion = "${var.flavor_bastion}"
|
||||
k8s_master_fips = "${module.ips.k8s_master_fips}"
|
||||
k8s_node_fips = "${module.ips.k8s_node_fips}"
|
||||
bastion_fips = "${module.ips.bastion_fips}"
|
||||
|
||||
network_id = "${module.network.router_id}"
|
||||
}
|
||||
|
||||
output "private_subnet_id" {
|
||||
value = "${module.network.subnet_id}"
|
||||
}
|
||||
|
||||
output "floating_network_id" {
|
||||
value = "${var.external_net}"
|
||||
}
|
||||
|
||||
output "router_id" {
|
||||
value = "${module.network.router_id}"
|
||||
}
|
||||
|
||||
output "k8s_master_fips" {
|
||||
value = "${module.ips.k8s_master_fips}"
|
||||
}
|
||||
|
||||
output "k8s_node_fips" {
|
||||
value = "${module.ips.k8s_node_fips}"
|
||||
}
|
||||
|
||||
output "bastion_fips" {
|
||||
value = "${module.ips.bastion_fips}"
|
||||
}
|
||||
|
|
|
@ -1,280 +1,306 @@
|
|||
|
||||
|
||||
variable user_data {
|
||||
type = "string"
|
||||
default = <<EOF
|
||||
#cloud-config
|
||||
manage_etc_hosts: localhost
|
||||
package_update: true
|
||||
package_upgrade: true
|
||||
EOF
|
||||
}
|
||||
resource "openstack_compute_keypair_v2" "k8s" {
|
||||
name = "kubernetes-${var.cluster_name}"
|
||||
public_key = "${chomp(file(var.public_key_path))}"
|
||||
name = "kubernetes-${var.cluster_name}"
|
||||
public_key = "${chomp(file(var.public_key_path))}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_secgroup_v2" "k8s_master" {
|
||||
name = "${var.cluster_name}-k8s-master"
|
||||
description = "${var.cluster_name} - Kubernetes Master"
|
||||
rule {
|
||||
ip_protocol = "tcp"
|
||||
from_port = "6443"
|
||||
to_port = "6443"
|
||||
cidr = "0.0.0.0/0"
|
||||
}
|
||||
name = "${var.cluster_name}-k8s-master"
|
||||
description = "${var.cluster_name} - Kubernetes Master"
|
||||
|
||||
rule {
|
||||
ip_protocol = "tcp"
|
||||
from_port = "6443"
|
||||
to_port = "6443"
|
||||
cidr = "0.0.0.0/0"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_secgroup_v2" "bastion" {
|
||||
name = "${var.cluster_name}-bastion"
|
||||
description = "${var.cluster_name} - Bastion Server"
|
||||
rule {
|
||||
ip_protocol = "tcp"
|
||||
from_port = "22"
|
||||
to_port = "22"
|
||||
cidr = "0.0.0.0/0"
|
||||
}
|
||||
name = "${var.cluster_name}-bastion"
|
||||
description = "${var.cluster_name} - Bastion Server"
|
||||
|
||||
rule {
|
||||
ip_protocol = "tcp"
|
||||
from_port = "22"
|
||||
to_port = "22"
|
||||
cidr = "0.0.0.0/0"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_secgroup_v2" "k8s" {
|
||||
name = "${var.cluster_name}-k8s"
|
||||
description = "${var.cluster_name} - Kubernetes"
|
||||
rule {
|
||||
ip_protocol = "icmp"
|
||||
from_port = "-1"
|
||||
to_port = "-1"
|
||||
cidr = "0.0.0.0/0"
|
||||
}
|
||||
rule {
|
||||
ip_protocol = "tcp"
|
||||
from_port = "1"
|
||||
to_port = "65535"
|
||||
self = true
|
||||
}
|
||||
rule {
|
||||
ip_protocol = "udp"
|
||||
from_port = "1"
|
||||
to_port = "65535"
|
||||
self = true
|
||||
}
|
||||
rule {
|
||||
ip_protocol = "icmp"
|
||||
from_port = "-1"
|
||||
to_port = "-1"
|
||||
self = true
|
||||
}
|
||||
name = "${var.cluster_name}-k8s"
|
||||
description = "${var.cluster_name} - Kubernetes"
|
||||
|
||||
rule {
|
||||
ip_protocol = "icmp"
|
||||
from_port = "-1"
|
||||
to_port = "-1"
|
||||
cidr = "0.0.0.0/0"
|
||||
}
|
||||
|
||||
rule {
|
||||
ip_protocol = "tcp"
|
||||
from_port = "1"
|
||||
to_port = "65535"
|
||||
self = true
|
||||
}
|
||||
|
||||
rule {
|
||||
ip_protocol = "udp"
|
||||
from_port = "1"
|
||||
to_port = "65535"
|
||||
self = true
|
||||
}
|
||||
|
||||
rule {
|
||||
ip_protocol = "icmp"
|
||||
from_port = "-1"
|
||||
to_port = "-1"
|
||||
self = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "bastion" {
|
||||
name = "${var.cluster_name}-bastion-${count.index+1}"
|
||||
count = "${var.number_of_bastions}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_bastion}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
security_groups = [ "${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"${openstack_compute_secgroup_v2.bastion.name}",
|
||||
"default" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "bastion"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
name = "${var.cluster_name}-bastion-${count.index+1}"
|
||||
count = "${var.number_of_bastions}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_bastion}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${var.bastion_fips[0]}/ > contrib/terraform/openstack/group_vars/no-floating.yml"
|
||||
}
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"${openstack_compute_secgroup_v2.bastion.name}",
|
||||
"default",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "bastion"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${var.bastion_fips[0]}/ > contrib/terraform/openstack/group_vars/no-floating.yml"
|
||||
}
|
||||
|
||||
user_data = "${var.user_data}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master" {
|
||||
name = "${var.cluster_name}-k8s-master-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
security_groups = [ "${openstack_compute_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_compute_secgroup_v2.bastion.name}",
|
||||
"${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"default" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,kube-node,k8s-cluster,vault"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
user_data = "${var.user_data}"
|
||||
name = "${var.cluster_name}-k8s-master-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_compute_secgroup_v2.bastion.name}",
|
||||
"${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"default",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,k8s-cluster,vault"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master_no_etcd" {
|
||||
name = "${var.cluster_name}-k8s-master-ne-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters_no_etcd}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
security_groups = [ "${openstack_compute_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_compute_secgroup_v2.k8s.name}" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-master,kube-node,k8s-cluster,vault"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
user_data = "${var.user_data}"
|
||||
name = "${var.cluster_name}-k8s-master-ne-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters_no_etcd}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_compute_secgroup_v2.k8s.name}",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-master,k8s-cluster,vault"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "etcd" {
|
||||
name = "${var.cluster_name}-etcd-${count.index+1}"
|
||||
count = "${var.number_of_etcd}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_etcd}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
security_groups = [ "${openstack_compute_secgroup_v2.k8s.name}" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
user_data = "${var.user_data}"
|
||||
name = "${var.cluster_name}-etcd-${count.index+1}"
|
||||
count = "${var.number_of_etcd}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_etcd}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s.name}"]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip" {
|
||||
name = "${var.cluster_name}-k8s-master-nf-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters_no_floating_ip}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
security_groups = [ "${openstack_compute_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"default" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,kube-node,k8s-cluster,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
user_data = "${var.user_data}"
|
||||
name = "${var.cluster_name}-k8s-master-nf-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters_no_floating_ip}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"default",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,k8s-cluster,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip_no_etcd" {
|
||||
name = "${var.cluster_name}-k8s-master-ne-nf-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters_no_floating_ip_no_etcd}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
security_groups = [ "${openstack_compute_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_compute_secgroup_v2.k8s.name}" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-master,kube-node,k8s-cluster,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
user_data = "${var.user_data}"
|
||||
name = "${var.cluster_name}-k8s-master-ne-nf-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters_no_floating_ip_no_etcd}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_compute_secgroup_v2.k8s.name}",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-master,k8s-cluster,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_node" {
|
||||
name = "${var.cluster_name}-k8s-node-${count.index+1}"
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
security_groups = [ "${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"${openstack_compute_secgroup_v2.bastion.name}",
|
||||
"default" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
user_data = "${var.user_data}"
|
||||
name = "${var.cluster_name}-k8s-node-${count.index+1}"
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"${openstack_compute_secgroup_v2.bastion.name}",
|
||||
"default",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_node_no_floating_ip" {
|
||||
name = "${var.cluster_name}-k8s-node-nf-${count.index+1}"
|
||||
count = "${var.number_of_k8s_nodes_no_floating_ip}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
security_groups = [ "${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"default" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
user_data = "${var.user_data}"
|
||||
name = "${var.cluster_name}-k8s-node-nf-${count.index+1}"
|
||||
count = "${var.number_of_k8s_nodes_no_floating_ip}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"default",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "bastion" {
|
||||
count = "${var.number_of_bastions}"
|
||||
floating_ip = "${var.bastion_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.bastion.*.id, count.index)}"
|
||||
count = "${var.number_of_bastions}"
|
||||
floating_ip = "${var.bastion_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.bastion.*.id, count.index)}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "k8s_master" {
|
||||
count = "${var.number_of_k8s_masters}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_master.*.id, count.index)}"
|
||||
floating_ip = "${var.k8s_master_fips[count.index]}"
|
||||
count = "${var.number_of_k8s_masters}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_master.*.id, count.index)}"
|
||||
floating_ip = "${var.k8s_master_fips[count.index]}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "k8s_node" {
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
floating_ip = "${var.k8s_node_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_node.*.id, count.index)}"
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
floating_ip = "${var.k8s_node_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_node.*.id, count.index)}"
|
||||
}
|
||||
|
||||
|
||||
resource "openstack_blockstorage_volume_v2" "glusterfs_volume" {
|
||||
name = "${var.cluster_name}-glusterfs_volume-${count.index+1}"
|
||||
count = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
name = "${var.cluster_name}-glusterfs_volume-${count.index+1}"
|
||||
count = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
description = "Non-ephemeral volume for GlusterFS"
|
||||
size = "${var.gfs_volume_size_in_gb}"
|
||||
size = "${var.gfs_volume_size_in_gb}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "glusterfs_node_no_floating_ip" {
|
||||
name = "${var.cluster_name}-gfs-node-nf-${count.index+1}"
|
||||
count = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
image_name = "${var.image_gfs}"
|
||||
flavor_id = "${var.flavor_gfs_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"default" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user_gfs}"
|
||||
kubespray_groups = "gfs-cluster,network-storage,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
user_data = "#cloud-config\nmanage_etc_hosts: localhost\npackage_update: true\npackage_upgrade: true"
|
||||
name = "${var.cluster_name}-gfs-node-nf-${count.index+1}"
|
||||
count = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
image_name = "${var.image_gfs}"
|
||||
flavor_id = "${var.flavor_gfs_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s.name}",
|
||||
"default",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user_gfs}"
|
||||
kubespray_groups = "gfs-cluster,network-storage,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resource "openstack_compute_volume_attach_v2" "glusterfs_volume" {
|
||||
count = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
count = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.glusterfs_node_no_floating_ip.*.id, count.index)}"
|
||||
volume_id = "${element(openstack_blockstorage_volume_v2.glusterfs_volume.*.id, count.index)}"
|
||||
}
|
||||
|
|
|
@ -1,74 +1,48 @@
|
|||
variable "cluster_name" {
|
||||
}
|
||||
variable "cluster_name" {}
|
||||
|
||||
variable "number_of_k8s_masters" {
|
||||
}
|
||||
variable "number_of_k8s_masters" {}
|
||||
|
||||
variable "number_of_k8s_masters_no_etcd" {
|
||||
}
|
||||
variable "number_of_k8s_masters_no_etcd" {}
|
||||
|
||||
variable "number_of_etcd" {
|
||||
}
|
||||
variable "number_of_etcd" {}
|
||||
|
||||
variable "number_of_k8s_masters_no_floating_ip" {
|
||||
}
|
||||
variable "number_of_k8s_masters_no_floating_ip" {}
|
||||
|
||||
variable "number_of_k8s_masters_no_floating_ip_no_etcd" {
|
||||
}
|
||||
variable "number_of_k8s_masters_no_floating_ip_no_etcd" {}
|
||||
|
||||
variable "number_of_k8s_nodes" {
|
||||
}
|
||||
variable "number_of_k8s_nodes" {}
|
||||
|
||||
variable "number_of_k8s_nodes_no_floating_ip" {
|
||||
}
|
||||
variable "number_of_k8s_nodes_no_floating_ip" {}
|
||||
|
||||
variable "number_of_bastions" {
|
||||
}
|
||||
variable "number_of_bastions" {}
|
||||
|
||||
variable "number_of_gfs_nodes_no_floating_ip" {
|
||||
}
|
||||
variable "number_of_gfs_nodes_no_floating_ip" {}
|
||||
|
||||
variable "gfs_volume_size_in_gb" {
|
||||
}
|
||||
variable "gfs_volume_size_in_gb" {}
|
||||
|
||||
variable "public_key_path" {
|
||||
}
|
||||
variable "public_key_path" {}
|
||||
|
||||
variable "image" {
|
||||
}
|
||||
variable "image" {}
|
||||
|
||||
variable "image_gfs" {
|
||||
}
|
||||
variable "image_gfs" {}
|
||||
|
||||
variable "ssh_user" {
|
||||
}
|
||||
variable "ssh_user" {}
|
||||
|
||||
variable "ssh_user_gfs" {
|
||||
}
|
||||
variable "ssh_user_gfs" {}
|
||||
|
||||
variable "flavor_k8s_master" {
|
||||
}
|
||||
variable "flavor_k8s_master" {}
|
||||
|
||||
variable "flavor_k8s_node" {
|
||||
}
|
||||
variable "flavor_k8s_node" {}
|
||||
|
||||
variable "flavor_etcd" {
|
||||
}
|
||||
variable "flavor_etcd" {}
|
||||
|
||||
variable "flavor_gfs_node" {
|
||||
}
|
||||
variable "flavor_gfs_node" {}
|
||||
|
||||
variable "network_name" {
|
||||
}
|
||||
variable "network_name" {}
|
||||
|
||||
variable "flavor_bastion" {
|
||||
}
|
||||
|
||||
|
||||
variable "network_id"{
|
||||
|
||||
}
|
||||
variable "flavor_bastion" {}
|
||||
|
||||
variable "network_id" {}
|
||||
|
||||
variable "k8s_master_fips" {
|
||||
type = "list"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
resource "null_resource" "dummy_dependency" {
|
||||
triggers {
|
||||
dependency_id = "${var.router_id}"
|
||||
|
@ -6,19 +5,19 @@ resource "null_resource" "dummy_dependency" {
|
|||
}
|
||||
|
||||
resource "openstack_networking_floatingip_v2" "k8s_master" {
|
||||
count = "${var.number_of_k8s_masters}"
|
||||
pool = "${var.floatingip_pool}"
|
||||
depends_on = ["null_resource.dummy_dependency"]
|
||||
count = "${var.number_of_k8s_masters}"
|
||||
pool = "${var.floatingip_pool}"
|
||||
depends_on = ["null_resource.dummy_dependency"]
|
||||
}
|
||||
|
||||
resource "openstack_networking_floatingip_v2" "k8s_node" {
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
pool = "${var.floatingip_pool}"
|
||||
depends_on = ["null_resource.dummy_dependency"]
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
pool = "${var.floatingip_pool}"
|
||||
depends_on = ["null_resource.dummy_dependency"]
|
||||
}
|
||||
|
||||
resource "openstack_networking_floatingip_v2" "bastion" {
|
||||
count = "${var.number_of_bastions}"
|
||||
pool = "${var.floatingip_pool}"
|
||||
depends_on = ["null_resource.dummy_dependency"]
|
||||
count = "${var.number_of_bastions}"
|
||||
pool = "${var.floatingip_pool}"
|
||||
depends_on = ["null_resource.dummy_dependency"]
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
output "k8s_master_fips" {
|
||||
value = ["${openstack_networking_floatingip_v2.k8s_master.*.address}"]
|
||||
value = ["${openstack_networking_floatingip_v2.k8s_master.*.address}"]
|
||||
}
|
||||
|
||||
output "k8s_node_fips" {
|
||||
value = ["${openstack_networking_floatingip_v2.k8s_node.*.address}"]
|
||||
value = ["${openstack_networking_floatingip_v2.k8s_node.*.address}"]
|
||||
}
|
||||
|
||||
output "bastion_fips" {
|
||||
value = ["${openstack_networking_floatingip_v2.bastion.*.address}"]
|
||||
value = ["${openstack_networking_floatingip_v2.bastion.*.address}"]
|
||||
}
|
||||
|
|
|
@ -1,26 +1,15 @@
|
|||
variable "number_of_k8s_masters" {
|
||||
}
|
||||
variable "number_of_k8s_masters" {}
|
||||
|
||||
variable "number_of_k8s_masters_no_etcd" {
|
||||
}
|
||||
variable "number_of_k8s_masters_no_etcd" {}
|
||||
|
||||
variable "number_of_k8s_nodes" {
|
||||
}
|
||||
variable "number_of_k8s_nodes" {}
|
||||
|
||||
variable "floatingip_pool" {
|
||||
}
|
||||
variable "floatingip_pool" {}
|
||||
|
||||
variable "number_of_bastions" {
|
||||
variable "number_of_bastions" {}
|
||||
|
||||
}
|
||||
variable "external_net" {}
|
||||
|
||||
variable "external_net" {
|
||||
variable "network_name" {}
|
||||
|
||||
}
|
||||
|
||||
variable "network_name" {
|
||||
}
|
||||
|
||||
variable "router_id"{
|
||||
|
||||
}
|
||||
variable "router_id" {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
resource "openstack_networking_router_v2" "k8s" {
|
||||
name = "${var.cluster_name}-router"
|
||||
admin_state_up = "true"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
output "router_id" {
|
||||
value = "${openstack_networking_router_interface_v2.k8s.id}"
|
||||
value = "${openstack_networking_router_interface_v2.k8s.id}"
|
||||
}
|
||||
|
||||
output "network_id" {
|
||||
value = "${openstack_networking_subnet_v2.k8s.id}"
|
||||
value = "${openstack_networking_subnet_v2.k8s.id}"
|
||||
}
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
variable "external_net" {
|
||||
variable "external_net" {}
|
||||
|
||||
}
|
||||
variable "network_name" {}
|
||||
|
||||
variable "network_name" {
|
||||
}
|
||||
variable "cluster_name" {}
|
||||
|
||||
variable "cluster_name" {
|
||||
}
|
||||
|
||||
variable "dns_nameservers"{
|
||||
variable "dns_nameservers" {
|
||||
type = "list"
|
||||
}
|
||||
|
|
|
@ -44,86 +44,70 @@ variable "gfs_volume_size_in_gb" {
|
|||
|
||||
variable "public_key_path" {
|
||||
description = "The path of the ssh pub key"
|
||||
default = "~/.ssh/id_rsa.pub"
|
||||
default = "~/.ssh/id_rsa.pub"
|
||||
}
|
||||
|
||||
variable "image" {
|
||||
description = "the image to use"
|
||||
default = "ubuntu-14.04"
|
||||
default = "ubuntu-14.04"
|
||||
}
|
||||
|
||||
variable "image_gfs" {
|
||||
description = "Glance image to use for GlusterFS"
|
||||
default = "ubuntu-16.04"
|
||||
default = "ubuntu-16.04"
|
||||
}
|
||||
|
||||
variable "ssh_user" {
|
||||
description = "used to fill out tags for ansible inventory"
|
||||
default = "ubuntu"
|
||||
default = "ubuntu"
|
||||
}
|
||||
|
||||
variable "ssh_user_gfs" {
|
||||
description = "used to fill out tags for ansible inventory"
|
||||
default = "ubuntu"
|
||||
default = "ubuntu"
|
||||
}
|
||||
|
||||
variable "flavor_bastion" {
|
||||
description = "Use 'nova flavor-list' command to see what your OpenStack instance uses for IDs"
|
||||
default = 3
|
||||
default = 3
|
||||
}
|
||||
|
||||
variable "flavor_k8s_master" {
|
||||
description = "Use 'nova flavor-list' command to see what your OpenStack instance uses for IDs"
|
||||
default = 3
|
||||
default = 3
|
||||
}
|
||||
|
||||
variable "flavor_k8s_node" {
|
||||
description = "Use 'nova flavor-list' command to see what your OpenStack instance uses for IDs"
|
||||
default = 3
|
||||
default = 3
|
||||
}
|
||||
|
||||
variable "flavor_etcd" {
|
||||
description = "Use 'nova flavor-list' command to see what your OpenStack instance uses for IDs"
|
||||
default = 3
|
||||
default = 3
|
||||
}
|
||||
|
||||
variable "flavor_gfs_node" {
|
||||
description = "Use 'nova flavor-list' command to see what your OpenStack instance uses for IDs"
|
||||
default = 3
|
||||
default = 3
|
||||
}
|
||||
|
||||
variable "network_name" {
|
||||
description = "name of the internal network to use"
|
||||
default = "internal"
|
||||
default = "internal"
|
||||
}
|
||||
|
||||
variable "dns_nameservers"{
|
||||
variable "dns_nameservers" {
|
||||
description = "An array of DNS name server names used by hosts in this subnet."
|
||||
type = "list"
|
||||
default = []
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "floatingip_pool" {
|
||||
description = "name of the floating ip pool to use"
|
||||
default = "external"
|
||||
default = "external"
|
||||
}
|
||||
|
||||
variable "external_net" {
|
||||
description = "uuid of the external/public network"
|
||||
}
|
||||
|
||||
variable "username" {
|
||||
description = "Your openstack username"
|
||||
}
|
||||
|
||||
variable "password" {
|
||||
description = "Your openstack password"
|
||||
}
|
||||
|
||||
variable "tenant" {
|
||||
description = "Your openstack tenant/project"
|
||||
}
|
||||
|
||||
variable "auth_url" {
|
||||
description = "Your openstack auth URL"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue