diff --git a/juju/home-maas-jammy/00-init.tf b/juju/home-maas-jammy/00-init.tf new file mode 100644 index 0000000..e54deec --- /dev/null +++ b/juju/home-maas-jammy/00-init.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + juju = { + version = "~> 0.12.0" + #source = "juju/juju" + source = "terraform.local/juju/juju" + } + } +} diff --git a/juju/home-maas-jammy/00-variables.tf b/juju/home-maas-jammy/00-variables.tf new file mode 100644 index 0000000..244a9d8 --- /dev/null +++ b/juju/home-maas-jammy/00-variables.tf @@ -0,0 +1,312 @@ +######## vars to change as per env +variable cloud { + type = string + default = "home-maas" +} + +variable num_units { + type = number + default = 3 +} + +variable controller_ids { + type = list(string) + default = ["100", "101", "102", + "103", "104", "105"] +} + +variable compute_ids { + type = list(string) + default = ["1000", "1001", "1002", "1003", + "1004", "1005", "1006", "1007"] +} + +variable sdn_ids { + type = list(string) + default = ["400", "401", "402"] +} + +variable apt_mirror { + type = string + default = "192.168.1.12" +} + +variable "all_services" { + type = list(string) + default = [ + "easyrsa", + "etcd", + "ceilometer", + "ceph-mon", +# "ceph-osd", + "ceph-radosgw", + "cinder", + "glance", + "gnocchi", + "heat", + "keystone", + "memcached", + "mysql-innodb-cluster", + "neutron-api", + "neutron-gateway", + "nova-compute-kvm", + "nova-cloud-controller", + "openstack-dashboard", + "placement", + "rabbitmq-server", + "vault", + ] +} + +######## vars unlikely to be changed +variable "machines" { + type = list(object({ + machine_id = number + constraints = string + })) +} + +variable model-name { + type = string + default = "openstack" +} + +variable openstack-origin { + type = string + default = "distro" +} + +variable openstack-region { + type = string + default = "RegionOne" +} + +variable openstack-channel { + type = string + default = "yoga/stable" +} + +variable ovn-channel { + type = string + default = "22.03/stable" +} + +variable default-base { + type = string + default = "ubuntu@22.04" +} + +variable mysql-channel { + type = string + default = "8.0/stable" +} + +variable mysql-router-channel { + type = string + default = "8.0/stable" +} + +variable hacluster-channel { + type = string + default = "2.4/stable" +} + +variable rabbitmq-server-channel { + type = string + default = "3.9/stable" +} + +variable ceph-channel { + type = string + default = "quincy/stable" +} + +variable lxd-snap-channel { + type = string + default = "5.21/stable" +} + +variable "sysconfig_channel" { + type = string + default = "latest/stable" +} + +variable "sysconfig_revision" { + type = string + default = "22" +} + +variable "ubuntu_channel" { + type = string + default = "latest/stable" +} + +variable "ubuntu_revision" { + type = string + default = "24" +} + +variable "vault_channel" { + type = string + default = "1.8/stable" +} + +variable "etcd_channel" { + type = string + default = "1.29/stable" +} + +variable "etcd_revision" { + type = string + default = "583" +} + +variable "easyrsa_channel" { + type = string + default = "latest/stable" +} + +variable osd-devices { + type = string + default = "" +} + +variable customize-failure-domain { + type = string + default = "true" +} + +variable reserved-host-memory { + type = number + default = 512 +} + +variable worker-multiplier { + type = number + default = 0.25 +} + +variable bridge-mappings { + type = string + default = "" + +} +variable data-port { + type = string + default = "" +} + +variable dns-servers { + type = string + default = "" +} + +variable nagios-context { + type = string + default = "" +} + +variable mysql-connections { + type = number + default = 4000 +} + +variable mysql-tuning-level { + type = string + default = "safest" +} + +variable vips { + type = map(string) + default = {} +} + +variable domain { + type = string + default = "openstack.local" +} + +variable fqdn-int { + type = map(string) + default = {} +} + +variable fqdn-admin { + type = map(string) + default = {} +} + +variable fqdn-pub { + type = map(string) + default = {} +} + +variable oam-space { + type = string + default = "oam" +} + +variable admin-space { + type = string + default = "admin" +} + +variable public-space { + type = string + default = "public" +} + +variable internal-space { + type = string + default = "internal" +} + +variable ceph-public-space { + type = string + default = "ceph-public" +} + +variable ceph-cluster-space { + type = string + default = "ceph-cluster" +} + +variable overlay-space { + type = string + default = "overlay" +} + +variable external-network-gateway { + type = string + default = "" +} + +variable cpu-allocation-ratio { + type = number + default = 16.0 +} + +variable ram-allocation-ratio { + type = number + default = 2.0 +} + +variable ntp-source { + type = string + default = "" +} + +variable external-network-cidr { + type = string + default = "" +} + +variable expected-osd-count { + type = number + default = 0 +} + +variable expected-mon-count { + type = number + default = 3 +} diff --git a/juju/home-maas-jammy/01-cloud.tf b/juju/home-maas-jammy/01-cloud.tf new file mode 100644 index 0000000..a970c6c --- /dev/null +++ b/juju/home-maas-jammy/01-cloud.tf @@ -0,0 +1,20 @@ +resource "juju_model" "openstack" { + name = var.model-name + + cloud { + name = var.cloud + } + + config = { + cloudinit-userdata = file("user-data.yaml") + + apt-mirror = "http://${var.apt_mirror}/archive.ubuntu.com/ubuntu" + lxd-snap-channel = var.lxd-snap-channel + + container-image-metadata-url = "http://${var.apt_mirror}/lxd/" + container-image-stream = "released" + + #agent-metadata-url = "http://${var.apt_mirror}/juju/tools/" + agent-stream = "released" + } +} diff --git a/juju/home-maas-jammy/03-machines.tf b/juju/home-maas-jammy/03-machines.tf new file mode 100644 index 0000000..19df533 --- /dev/null +++ b/juju/home-maas-jammy/03-machines.tf @@ -0,0 +1,9 @@ +resource "juju_machine" "all_machines" { + for_each = { + for index, machine in var.machines: + machine.machine_id => machine + } + model = var.model-name + name = each.value.machine_id + constraints = each.value.constraints +} diff --git a/juju/home-maas-jammy/04-keystone.tf b/juju/home-maas-jammy/04-keystone.tf new file mode 100644 index 0000000..0c7c2a7 --- /dev/null +++ b/juju/home-maas-jammy/04-keystone.tf @@ -0,0 +1,136 @@ +resource "juju_machine" "keystone" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index+var.num_units]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "keystone" { + name = "keystone" + + model = var.model-name + + charm { + name = "keystone" + channel = var.openstack-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.keystone : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.public-space + endpoint = "public" + },{ + space = var.admin-space + endpoint = "admin" + },{ + space = var.internal-space + endpoint = "internal" + },{ + space = var.internal-space + endpoint = "shared-db" + }] + + config = { + worker-multiplier = var.worker-multiplier + openstack-origin = var.openstack-origin + vip = var.vips["keystone"] + region = var.openstack-region + preferred-api-version = "3" + token-provider = "fernet" + admin-password = "openstack" + } +} + +resource "juju_application" "keystone-mysql-router" { + name = "keystone-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "shared-db" + },{ + space = var.internal-space + endpoint = "db-router" + }] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-keystone" { + name = "hacluster-keystone" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "keystone-ha" { + + model = var.model-name + + application { + name = juju_application.keystone.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-keystone.name + endpoint = "ha" + } +} + +resource "juju_integration" "keystone-mysql" { + + model = var.model-name + + application { + name = juju_application.keystone.name + endpoint = "shared-db" + } + + application { + name = juju_application.keystone-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "keystone-db" { + + model = var.model-name + + application { + name = juju_application.keystone-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} diff --git a/juju/home-maas-jammy/04-mysql.tf b/juju/home-maas-jammy/04-mysql.tf new file mode 100644 index 0000000..277d0ff --- /dev/null +++ b/juju/home-maas-jammy/04-mysql.tf @@ -0,0 +1,44 @@ +resource "juju_machine" "mysql" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "mysql-innodb-cluster" { + name = "mysql-innodb-cluster" + + model = var.model-name + + charm { + name = "mysql-innodb-cluster" + channel = var.mysql-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.mysql : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "cluster" + space = var.internal-space + },{ + endpoint = "db-router" + space = var.internal-space + }] + + config = { + source = var.openstack-origin + wait-timeout = "3600" + enable-binlogs = "false" + snapd_refresh = "max" + max-connections = var.mysql-connections + tuning-level = var.mysql-tuning-level + } +} diff --git a/juju/home-maas-jammy/04-rmq.tf b/juju/home-maas-jammy/04-rmq.tf new file mode 100644 index 0000000..bd9fc48 --- /dev/null +++ b/juju/home-maas-jammy/04-rmq.tf @@ -0,0 +1,41 @@ +resource "juju_machine" "rmq" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index+var.num_units]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "rabbitmq-server" { + name = "rabbitmq-server" + + model = var.model-name + + charm { + name = "rabbitmq-server" + channel = var.rabbitmq-server-channel + base = var.default-base + } + + units = 3 + + placement = "${join(",", sort([ + for res in juju_machine.rmq : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "amqp" + space = var.internal-space + },{ + endpoint = "cluster" + space = var.internal-space + }] + + config = { + source = var.openstack-origin + min-cluster-size = "3" + cluster-partition-handling = "pause_minority" + } +} diff --git a/juju/home-maas-jammy/05-ceph.tf b/juju/home-maas-jammy/05-ceph.tf new file mode 100644 index 0000000..5dfee2b --- /dev/null +++ b/juju/home-maas-jammy/05-ceph.tf @@ -0,0 +1,206 @@ +resource "juju_application" "ceph-osd" { + name = "ceph-osd" + + model = var.model-name + + charm { + name = "ceph-osd" + channel = var.ceph-channel + base = var.default-base + } + + units = length(var.compute_ids) + + placement = "${join(",", sort([ + for index in var.compute_ids : + juju_machine.all_machines[index].machine_id + ]))}" + + config = { + osd-devices = var.osd-devices + source = var.openstack-origin + aa-profile-mode = "complain" + customize-failure-domain = "true" + autotune = "false" + bluestore = "true" + osd-encrypt = "true" + osd-encrypt-keymanager = "vault" + } +} + +resource "juju_machine" "ceph-mon" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index]].machine_id]) + constraints = "spaces=oam,ceph-access,ceph-replica" +} + +resource "juju_application" "ceph-mon" { + name = "ceph-mon" + + model = var.model-name + + charm { + name = "ceph-mon" + channel = var.ceph-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.ceph-mon : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "public" + space = var.ceph-public-space + },{ + endpoint = "osd" + space = var.ceph-public-space + },{ + endpoint = "client" + space = var.ceph-public-space + },{ + endpoint = "admin" + space = var.ceph-public-space + },{ + endpoint = "cluster" + space = var.ceph-cluster-space + }] + + config = { + expected-osd-count = var.expected-osd-count + source = var.openstack-origin + monitor-count = var.expected-mon-count + customize-failure-domain = true + } +} + +resource "juju_machine" "ceph-rgw" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index]].machine_id]) + constraints = "spaces=oam,ceph-access" +} + +resource "juju_application" "ceph-radosgw" { + name = "ceph-radosgw" + + model = var.model-name + + charm { + name = "ceph-radosgw" + channel = var.ceph-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.ceph-rgw : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.public-space + endpoint = "public" + },{ + space = var.admin-space + endpoint = "admin" + },{ + space = var.internal-space + endpoint = "internal" + },{ + space = var.ceph-public-space + endpoint = "mon" + }] + + config = { + source = var.openstack-origin + vip = var.vips["radosgw"] + operator-roles = "Member,admin" + region = var.openstack-region + os-admin-hostname = "${join(".",[var.fqdn-admin["radosgw"],var.domain])}" + os-internal-hostname = "${join(".",[var.fqdn-int["radosgw"],var.domain])}" + os-public-hostname = "${join(".",[var.fqdn-pub["radosgw"],var.domain])}" + } +} + +resource "juju_application" "hacluster-radosgw" { + name = "hacluster-radosgw" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "osd-mon" { + + model = var.model-name + + application { + name = juju_application.ceph-osd.name + endpoint = "mon" + } + + application { + name = juju_application.ceph-mon.name + endpoint = "osd" + } +} + +resource "juju_integration" "rgw-mon" { + + model = var.model-name + + application { + name = juju_application.ceph-radosgw.name + endpoint = "mon" + } + + application { + name = juju_application.ceph-mon.name + endpoint = "radosgw" + } +} + +resource "juju_integration" "rgw-ha" { + + model = var.model-name + + application { + name = juju_application.ceph-radosgw.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-radosgw.name + endpoint = "ha" + } +} + +resource "juju_integration" "rgw-keystone" { + + model = var.model-name + + application { + name = juju_application.ceph-radosgw.name + endpoint = "identity-service" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-service" + } +} diff --git a/juju/home-maas-jammy/05-cinder.tf b/juju/home-maas-jammy/05-cinder.tf new file mode 100644 index 0000000..994e153 --- /dev/null +++ b/juju/home-maas-jammy/05-cinder.tf @@ -0,0 +1,230 @@ +resource "juju_machine" "cinder" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "cinder" { + name = "cinder" + + model = var.model-name + + charm { + name = "cinder" + channel = var.openstack-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.cinder : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "public" + space = var.public-space + },{ + endpoint = "admin" + space = var.admin-space + },{ + endpoint = "internal" + space = var.internal-space + },{ + endpoint = "shared-db" + space = var.internal-space + }] + + config = { + worker-multiplier = var.worker-multiplier + openstack-origin = var.openstack-origin + region = var.openstack-region + vip = var.vips["cinder"] + use-internal-endpoints = "true" + block-device = "None" + glance-api-version = "2" + enabled-services = "api,scheduler,volume" + } +} + +resource "juju_application" "cinder-ceph" { + name = "cinder-ceph" + + model = var.model-name + + charm { + name = "cinder-ceph" + channel = var.openstack-channel + } + + units = 0 + + config = { + restrict-ceph-pools = "false" + } +} + + +resource "juju_application" "cinder-mysql-router" { + name = "cinder-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "shared-db" + },{ + space = var.internal-space + endpoint = "db-router" + }] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-cinder" { + name = "hacluster-cinder" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "cinder-ha" { + + model = var.model-name + + application { + name = juju_application.cinder.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-cinder.name + endpoint = "ha" + } +} + +resource "juju_integration" "cinder-mysql" { + + model = var.model-name + + application { + name = juju_application.cinder.name + endpoint = "shared-db" + } + + application { + name = juju_application.cinder-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "cinder-db" { + + model = var.model-name + + application { + name = juju_application.cinder-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} + +resource "juju_integration" "cinder-rmq" { + + model = var.model-name + + application { + name = juju_application.cinder.name + endpoint = "amqp" + } + + application { + name = juju_application.rabbitmq-server.name + endpoint = "amqp" + } +} + +resource "juju_integration" "cinder-keystone" { + + model = var.model-name + + application { + name = juju_application.cinder.name + endpoint = "identity-service" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-service" + } +} + +resource "juju_integration" "cinder-ceph" { + + model = var.model-name + + application { + name = juju_application.cinder.name + endpoint = "ceph" + } + + application { + name = juju_application.ceph-mon.name + endpoint = "client" + } +} + +resource "juju_integration" "cinder-ceph-mon" { + + model = var.model-name + + application { + name = juju_application.cinder-ceph.name + endpoint = "ceph" + } + + application { + name = juju_application.ceph-mon.name + endpoint = "client" + } +} + +resource "juju_integration" "cinder-ceph-cinder" { + + model = var.model-name + + application { + name = juju_application.cinder-ceph.name + endpoint = "storage-backend" + } + + application { + name = juju_application.cinder.name + endpoint = "storage-backend" + } +} diff --git a/juju/home-maas-jammy/05-glance.tf b/juju/home-maas-jammy/05-glance.tf new file mode 100644 index 0000000..dc19649 --- /dev/null +++ b/juju/home-maas-jammy/05-glance.tf @@ -0,0 +1,196 @@ +resource "juju_machine" "glance" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "glance" { + name = "glance" + + model = var.model-name + + charm { + name = "glance" + channel = var.openstack-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.glance : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "public" + space = var.public-space + },{ + endpoint = "admin" + space = var.admin-space + },{ + endpoint = "internal" + space = var.internal-space + },{ + endpoint = "shared-db" + space = var.internal-space + }] + + config = { + worker-multiplier = var.worker-multiplier + openstack-origin = var.openstack-origin + region = var.openstack-region + vip = var.vips["glance"] + use-internal-endpoints = "true" + restrict-ceph-pools = "false" + } +} + +resource "juju_application" "glance-mysql-router" { + name = "glance-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "shared-db" + },{ + space = var.internal-space + endpoint = "db-router" + }] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-glance" { + name = "hacluster-glance" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "glance-ha" { + + + model = var.model-name + + application { + name = juju_application.glance.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-glance.name + endpoint = "ha" + } +} + +resource "juju_integration" "glance-mysql" { + + model = var.model-name + + application { + name = juju_application.glance.name + endpoint = "shared-db" + } + + application { + name = juju_application.glance-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "glance-db" { + + model = var.model-name + + application { + name = juju_application.glance-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} + +resource "juju_integration" "glance-rmq" { + + model = var.model-name + + application { + name = juju_application.glance.name + endpoint = "amqp" + } + + application { + name = juju_application.rabbitmq-server.name + endpoint = "amqp" + } +} + +resource "juju_integration" "glance-keystone" { + + model = var.model-name + + application { + name = juju_application.glance.name + endpoint = "identity-service" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-service" + } +} + +resource "juju_integration" "glance-ceph" { + + model = var.model-name + + application { + name = juju_application.glance.name + endpoint = "ceph" + } + + application { + name = juju_application.ceph-mon.name + endpoint = "client" + } +} + +resource "juju_integration" "glance-cinder" { + + model = var.model-name + + application { + name = juju_application.glance.name + endpoint = "image-service" + } + + application { + name = juju_application.cinder.name + endpoint = "image-service" + } +} diff --git a/juju/home-maas-jammy/05-heat.tf b/juju/home-maas-jammy/05-heat.tf new file mode 100644 index 0000000..d20d51f --- /dev/null +++ b/juju/home-maas-jammy/05-heat.tf @@ -0,0 +1,165 @@ +resource "juju_machine" "heat" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "heat" { + name = "heat" + + model = var.model-name + + charm { + name = "heat" + channel = var.openstack-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.heat : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "public" + space = var.public-space + },{ + endpoint = "admin" + space = var.admin-space + },{ + endpoint = "internal" + space = var.internal-space + },{ + endpoint = "shared-db" + space = var.internal-space + }] + + config = { + worker-multiplier = var.worker-multiplier + openstack-origin = var.openstack-origin + region = var.openstack-region + vip = var.vips["heat"] + use-internal-endpoints = "true" + config-flags = "max_nested_stack_depth=20" + } +} + +resource "juju_application" "heat-mysql-router" { + name = "heat-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "shared-db" + },{ + space = var.internal-space + endpoint = "db-router" + }] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-heat" { + name = "hacluster-heat" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "heat-ha" { + + model = var.model-name + + application { + name = juju_application.heat.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-heat.name + endpoint = "ha" + } +} + +resource "juju_integration" "heat-mysql" { + + model = var.model-name + + application { + name = juju_application.heat.name + endpoint = "shared-db" + } + + application { + name = juju_application.heat-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "heat-db" { + + model = var.model-name + + application { + name = juju_application.heat-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} + +resource "juju_integration" "heat-rmq" { + + model = var.model-name + + application { + name = juju_application.heat.name + endpoint = "amqp" + } + + application { + name = juju_application.rabbitmq-server.name + endpoint = "amqp" + } +} + +resource "juju_integration" "heat-keystone" { + + model = var.model-name + + application { + name = juju_application.heat.name + endpoint = "identity-service" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-service" + } +} diff --git a/juju/home-maas-jammy/05-memcache.tf b/juju/home-maas-jammy/05-memcache.tf new file mode 100644 index 0000000..b8efaab --- /dev/null +++ b/juju/home-maas-jammy/05-memcache.tf @@ -0,0 +1,52 @@ +resource "juju_machine" "memcache" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "memcached" { + name = "memcached" + + model = var.model-name + + charm { + name = "memcached" + channel = "latest/stable" + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.memcache : + res.machine_id + ]))}" + + + endpoint_bindings = [{ + space = var.internal-space + },{ + endpoint = "cache" + space = var.internal-space + }] + + config = { + allow-ufw-ip6-softfail = "true" + } +} + +resource "juju_integration" "nova-cloud-controller-memcache" { + + model = var.model-name + + application { + name = juju_application.nova-cloud-controller.name + endpoint = "memcache" + } + + application { + name = juju_application.memcached.name + endpoint = "cache" + } +} diff --git a/juju/home-maas-jammy/05-nova.tf b/juju/home-maas-jammy/05-nova.tf new file mode 100644 index 0000000..d833a28 --- /dev/null +++ b/juju/home-maas-jammy/05-nova.tf @@ -0,0 +1,217 @@ +resource "juju_machine" "ncc" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index+var.num_units]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "nova-cloud-controller" { + name = "nova-cloud-controller" + + model = var.model-name + + charm { + name = "nova-cloud-controller" + channel = var.openstack-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.ncc : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "public" + space = var.public-space + },{ + endpoint = "admin" + space = var.admin-space + },{ + endpoint = "internal" + space = var.internal-space + },{ + endpoint = "shared-db" + space = var.internal-space + },{ + endpoint = "memcache" + space = var.internal-space + }] + + config = { + worker-multiplier = var.worker-multiplier + openstack-origin = var.openstack-origin + region = var.openstack-region + vip = var.vips["nova-cc"] + network-manager = "Neutron" + console-access-protocol = "novnc" + console-proxy-ip = "local" + use-internal-endpoints = "true" + ram-allocation-ratio = var.ram-allocation-ratio + cpu-allocation-ratio = var.cpu-allocation-ratio + config-flags = "scheduler_max_attempts=20" + } +} + +resource "juju_application" "nova-cloud-controller-mysql-router" { + name = "nova-cloud-controller-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "shared-db" + },{ + space = var.internal-space + endpoint = "db-router" + }] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-nova" { + name = "hacluster-nova" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "nova-cloud-controller-ha" { + + model = var.model-name + + application { + name = juju_application.nova-cloud-controller.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-nova.name + endpoint = "ha" + } +} + +resource "juju_integration" "nova-cloud-controller-mysql" { + + model = var.model-name + + application { + name = juju_application.nova-cloud-controller.name + endpoint = "shared-db" + } + + application { + name = juju_application.nova-cloud-controller-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "nova-cloud-controller-db" { + + model = var.model-name + + application { + name = juju_application.nova-cloud-controller-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} + +resource "juju_integration" "nova-cloud-controller-rmq" { + + model = var.model-name + + application { + name = juju_application.nova-cloud-controller.name + endpoint = "amqp" + } + + application { + name = juju_application.rabbitmq-server.name + endpoint = "amqp" + } +} + +resource "juju_integration" "nova-cloud-controller-keystone" { + + model = var.model-name + + application { + name = juju_application.nova-cloud-controller.name + endpoint = "identity-service" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-service" + } +} + +resource "juju_integration" "nova-cloud-controller-neutron" { + + model = var.model-name + + application { + name = juju_application.nova-cloud-controller.name + endpoint = "neutron-api" + } + + application { + name = juju_application.neutron-api.name + endpoint = "neutron-api" + } +} + +resource "juju_integration" "nova-cloud-controller-nova-compute" { + + model = var.model-name + + application { + name = juju_application.nova-cloud-controller.name + endpoint = "cloud-compute" + } + + application { + name = juju_application.nova-compute-kvm.name + endpoint = "cloud-compute" + } +} +resource "juju_integration" "nova-cloud-controller-glance" { + + model = var.model-name + + application { + name = juju_application.nova-cloud-controller.name + endpoint = "image-service" + } + + application { + name = juju_application.glance.name + endpoint = "image-service" + } +} diff --git a/juju/home-maas-jammy/05-placement.tf b/juju/home-maas-jammy/05-placement.tf new file mode 100644 index 0000000..e702425 --- /dev/null +++ b/juju/home-maas-jammy/05-placement.tf @@ -0,0 +1,166 @@ +resource "juju_machine" "placement" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index+var.num_units]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "placement" { + name = "placement" + + model = var.model-name + + charm { + name = "placement" + channel = var.openstack-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.placement : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "public" + space = var.public-space + },{ + endpoint = "admin" + space = var.admin-space + },{ + endpoint = "internal" + space = var.internal-space + },{ + endpoint = "shared-db" + space = var.internal-space + }] + + config = { + worker-multiplier = var.worker-multiplier + openstack-origin = var.openstack-origin + vip = var.vips["placement"] + #os-admin-hostname = "${join(".",[var.fqdn-admin["placement"],var.domain])}" + #os-internal-hostname = "${join(".",[var.fqdn-int["placement"],var.domain])}" + #os-public-hostname = "${join(".",[var.fqdn-pub["placement"],var.domain])}" + + } +} + +resource "juju_application" "placement-mysql-router" { + name = "placement-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "shared-db" + },{ + space = var.internal-space + endpoint = "db-router" + }] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-placement" { + name = "hacluster-placement" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "placement-ha" { + + model = var.model-name + + application { + name = juju_application.placement.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-placement.name + endpoint = "ha" + } +} + +resource "juju_integration" "placement-mysql" { + + model = var.model-name + + application { + name = juju_application.placement.name + endpoint = "shared-db" + } + + application { + name = juju_application.placement-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "placement-db" { + + model = var.model-name + + application { + name = juju_application.placement-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} + +resource "juju_integration" "placement-keystone" { + + model = var.model-name + + application { + name = juju_application.placement.name + endpoint = "identity-service" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-service" + } +} + +resource "juju_integration" "placement-nova" { + + model = var.model-name + + application { + name = juju_application.placement.name + endpoint = "placement" + } + + application { + name = juju_application.nova-cloud-controller.name + endpoint = "placement" + } +} diff --git a/juju/home-maas-jammy/06-nova-compute.tf b/juju/home-maas-jammy/06-nova-compute.tf new file mode 100644 index 0000000..de50f99 --- /dev/null +++ b/juju/home-maas-jammy/06-nova-compute.tf @@ -0,0 +1,205 @@ +resource "juju_application" "nova-compute-kvm" { + name = "nova-compute-kvm" + + model = var.model-name + + charm { + name = "nova-compute" + channel = var.openstack-channel + base = var.default-base + } + + units = length(var.compute_ids) + + placement = "${join(",", sort([ + for index in var.compute_ids : + juju_machine.all_machines[index].machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "internal" + }] + + config = { + openstack-origin = var.openstack-origin + enable-live-migration = "true" + enable-resize = "true" + migration-auth-type = "ssh" + use-internal-endpoints = "true" + libvirt-image-backend = "rbd" + restrict-ceph-pools = "false" + aa-profile-mode = "complain" + virt-type = "kvm" + customize-failure-domain = var.customize-failure-domain + reserved-host-memory = var.reserved-host-memory + cpu-allocation-ratio = var.cpu-allocation-ratio + ram-allocation-ratio = var.ram-allocation-ratio + #cpu-mode = "custom" + #cpu-model = "EPYC-IBPB" + #cpu-model-extra-flags = "svm,pcid" + pci-passthrough-whitelist = jsonencode([ + {vendor_id: "1af4", product_id: "1000", address: "00:08.0"}, + {vendor_id: "1af4", product_id: "1000", address: "00:07.0"}, + {vendor_id: "1af4", product_id: "1000", address: "00:06.0"}, + ]) + pci-alias = jsonencode({ + vendor_id: "1af4", + product_id: "1000", + device_type: "type-PCI", + name: "arifpass", + numa_policy: "preferred" + }) + } +} + +resource "juju_application" "ovn-chassis" { + name = "ovn-chassis" + + model = var.model-name + + charm { + name = "ovn-chassis" + channel = var.ovn-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + }] + + config = { + bridge-interface-mappings = var.data-port + ovn-bridge-mappings = var.bridge-mappings + } +} + +resource "juju_application" "sysconfig-compute" { + name = "sysconfig-compute" + + model = var.model-name + + charm { + name = "sysconfig" + channel = var.sysconfig_channel + revision = var.sysconfig_revision + } + + units = 0 + + config = { +# enable-iommu = "false" + governor = "performance" + enable-pti = "on" + update-grub = "true" + enable-tsx = "true" + } +} + +resource "juju_integration" "compute-ovn" { + + model = var.model-name + + application { + name = juju_application.ovn-chassis.name + endpoint = "nova-compute" + } + + application { + name = juju_application.nova-compute-kvm.name + endpoint = "neutron-plugin" + } +} + +resource "juju_integration" "compute-sysconfig" { + + model = var.model-name + + application { + name = juju_application.nova-compute-kvm.name + endpoint = "juju-info" + } + + application { + name = juju_application.sysconfig-compute.name + endpoint = "juju-info" + } +} + +resource "juju_integration" "compute-ceph-mon" { + + model = var.model-name + + application { + name = juju_application.nova-compute-kvm.name + endpoint = "ceph" + } + + application { + name = juju_application.ceph-mon.name + endpoint = "client" + } +} + +resource "juju_integration" "chassis-central" { + + model = var.model-name + + application { + name = juju_application.ovn-chassis.name + endpoint = "ovsdb" + } + + application { + name = juju_application.ovn-central.name + endpoint = "ovsdb" + } +} + +resource "juju_integration" "nova-compute-rmq" { + + model = var.model-name + + application { + name = juju_application.nova-compute-kvm.name + endpoint = "amqp" + } + + application { + name = juju_application.rabbitmq-server.name + endpoint = "amqp" + } +} + +resource "juju_integration" "nova-compute-glance" { + + model = var.model-name + + application { + name = juju_application.nova-compute-kvm.name + endpoint = "image-service" + } + + application { + name = juju_application.glance.name + endpoint = "image-service" + } +} + +resource "juju_integration" "nova-compute-cinder-ceph" { + + model = var.model-name + + application { + name = juju_application.nova-compute-kvm.name + endpoint = "ceph-access" + } + + application { + name = juju_application.cinder-ceph.name + endpoint = "ceph-access" + } +} diff --git a/juju/home-maas-jammy/06-openstack-dashboard.tf b/juju/home-maas-jammy/06-openstack-dashboard.tf new file mode 100644 index 0000000..8473103 --- /dev/null +++ b/juju/home-maas-jammy/06-openstack-dashboard.tf @@ -0,0 +1,146 @@ +resource "juju_machine" "openstack-dashboard" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index]].machine_id]) + constraints = "spaces=oam,ceph-access" +} + +resource "juju_application" "openstack-dashboard" { + name = "openstack-dashboard" + + model = var.model-name + + charm { + name = "openstack-dashboard" + channel = var.openstack-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.openstack-dashboard : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "shared-db" + space = var.internal-space + }] + + config = { + openstack-origin = var.openstack-origin + vip = var.vips["dashboard"] + webroot = "/" + secret = "encryptcookieswithme" + cinder-backup = "false" + password-retrieve = "true" + endpoint-type = "publicURL" + + neutron-network-l3ha = "true" + neutron-network-lb = "true" + neutron-network-firewall = "false" + } +} + +resource "juju_application" "openstack-dashboard-mysql-router" { + name = "openstack-dashboard-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "shared-db" + },{ + space = var.internal-space + endpoint = "db-router" + }] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-openstack-dashboard" { + name = "hacluster-openstack-dashboard" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "openstack-dashboard-ha" { + + model = var.model-name + + application { + name = juju_application.openstack-dashboard.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-openstack-dashboard.name + endpoint = "ha" + } +} + +resource "juju_integration" "openstack-dashboard-mysql" { + + model = var.model-name + + application { + name = juju_application.openstack-dashboard.name + endpoint = "shared-db" + } + + application { + name = juju_application.openstack-dashboard-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "openstack-dashboard-db" { + + model = var.model-name + + application { + name = juju_application.openstack-dashboard-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} + +resource "juju_integration" "openstack-dashboard-keystone" { + + model = var.model-name + + application { + name = juju_application.openstack-dashboard.name + endpoint = "identity-service" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-service" + } +} diff --git a/juju/home-maas-jammy/07-controllers.tf b/juju/home-maas-jammy/07-controllers.tf new file mode 100644 index 0000000..3453d5f --- /dev/null +++ b/juju/home-maas-jammy/07-controllers.tf @@ -0,0 +1,55 @@ +resource "juju_application" "controller-server" { + name = "controller-server" + + model = var.model-name + + charm { + name = "ubuntu" + channel = var.ubuntu_channel + revision = var.ubuntu_revision + base = var.default-base + } + + units = length(var.controller_ids) + + placement = "${join(",", sort([ + for index in var.controller_ids : + juju_machine.all_machines[index].machine_id + ]))}" +} + +resource "juju_application" "sysconfig-control" { + name = "sysconfig-control" + + model = var.model-name + + charm { + name = "sysconfig" + channel = var.sysconfig_channel + revision = var.sysconfig_revision + } + + units = 0 + + config = { + governor = "performance" + enable-pti = "on" + update-grub = "true" + enable-tsx = "true" + } +} + +resource "juju_integration" "control-sysconfig" { + + model = var.model-name + + application { + name = juju_application.sysconfig-control.name + endpoint = "juju-info" + } + + application { + name = juju_application.controller-server.name + endpoint = "juju-info" + } +} diff --git a/juju/home-maas-jammy/08-neutron.tf b/juju/home-maas-jammy/08-neutron.tf new file mode 100644 index 0000000..aebac3e --- /dev/null +++ b/juju/home-maas-jammy/08-neutron.tf @@ -0,0 +1,252 @@ +resource "juju_machine" "ovn-central" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index+var.num_units]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "ovn-central" { + name = "ovn-central" + + model = var.model-name + + charm { + name = "ovn-central" + channel = var.ovn-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.ovn-central : + res.machine_id + ]))}" + +} + +resource "juju_machine" "neutron-api" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "neutron-api" { + name = "neutron-api" + + model = var.model-name + + charm { + name = "neutron-api" + channel = var.openstack-channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.neutron-api : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "public" + space = var.public-space + },{ + endpoint = "admin" + space = var.admin-space + },{ + endpoint = "internal" + space = var.internal-space + },{ + endpoint = "shared-db" + space = var.internal-space + }] + + config = { + worker-multiplier = var.worker-multiplier + openstack-origin = var.openstack-origin + region = var.openstack-region + vip = var.vips["neutron-api"] + neutron-security-groups = "true" + use-internal-endpoints = "true" + enable-l3ha = "true" + dhcp-agents-per-network = "2" + enable-ml2-port-security = "true" + l2-population = "true" + vlan-ranges = "physnet1:350:599" + flat-network-providers = "physnet1" + enable-vlan-trunking = "false" + manage-neutron-plugin-legacy-mode = "false" + neutron-security-groups = "true" + #default-tenant-network-type = "vxlan" + overlay-network-type = "gre" + } +} + +resource "juju_application" "neutron-api-plugin-ovn" { + name = "neutron-api-plugin-ovn" + + model = var.model-name + + charm { + name = "neutron-api-plugin-ovn" + channel = var.openstack-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + }] +} + + +resource "juju_application" "neutron-mysql-router" { + name = "neutron-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "shared-db" + },{ + space = var.internal-space + endpoint = "db-router" + }] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-neutron" { + name = "hacluster-neutron" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "neutron-ha" { + + model = var.model-name + + application { + name = juju_application.neutron-api.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-neutron.name + endpoint = "ha" + } +} + +resource "juju_integration" "neutron-mysql" { + + model = var.model-name + + application { + name = juju_application.neutron-api.name + endpoint = "shared-db" + } + + application { + name = juju_application.neutron-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "neutron-db" { + + model = var.model-name + + application { + name = juju_application.neutron-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} + +resource "juju_integration" "neutron-keystone" { + + model = var.model-name + + application { + name = juju_application.neutron-api.name + endpoint = "identity-service" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-service" + } +} + +resource "juju_integration" "neutron-api-rmq" { + + model = var.model-name + + application { + name = juju_application.neutron-api.name + endpoint = "amqp" + } + + application { + name = juju_application.rabbitmq-server.name + endpoint = "amqp" + } +} + +resource "juju_integration" "neutron-api-plugin-ovn" { + + model = var.model-name + + application { + name = juju_application.neutron-api.name + endpoint = "neutron-plugin-api-subordinate" + } + + application { + name = juju_application.neutron-api-plugin-ovn.name + endpoint = "neutron-plugin" + } +} + +resource "juju_integration" "neutron-api-plugin-ovn-central" { + + model = var.model-name + + application { + name = juju_application.ovn-central.name + endpoint = "ovsdb-cms" + } + + application { + name = juju_application.neutron-api-plugin-ovn.name + endpoint = "ovsdb-cms" + } +} + diff --git a/juju/home-maas-jammy/10-vault.tf b/juju/home-maas-jammy/10-vault.tf new file mode 100644 index 0000000..445a473 --- /dev/null +++ b/juju/home-maas-jammy/10-vault.tf @@ -0,0 +1,265 @@ +resource "juju_machine" "vault" { + count = var.num_units + model = var.model-name + placement = join(":",["lxd",juju_machine.all_machines[var.sdn_ids[count.index]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "vault" { + name = "vault" + + model = var.model-name + + charm { + name = "vault" + channel = var.vault_channel + base = var.default-base + } + + units = var.num_units + + placement = "${join(",",sort([ + for res in juju_machine.vault : + res.machine_id + ]))}" + + config = { + vip = var.vips["vault"] + nagios_context = var.nagios-context + } + +} + +resource "juju_application" "vault-mysql-router" { + name = "vault-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [ + { + space = var.oam-space + },{ + endpoint = "shared-db" + space = var.internal-space + },{ + endpoint = "db-router" + space = var.internal-space + }, + ] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-vault" { + name = "hacluster-vault" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + + +resource "juju_machine" "etcd" { + count = var.num_units + model = var.model-name + placement = join(":",["lxd",juju_machine.all_machines[var.sdn_ids[count.index]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "etcd" { + name = "etcd" + + model = var.model-name + + charm { + name = "etcd" + channel = var.etcd_channel + base = var.default-base + #revision = var.etcd_revision + } + + placement = "${join(",",sort([ + for res in juju_machine.etcd : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "cluster" + },{ + space = var.internal-space + endpoint = "db" + }] + + units = var.num_units + + config = { + channel = "3.2/stable" + } +} + +resource "juju_machine" "easyrsa" { + model = var.model-name + placement = join(":",["lxd",juju_machine.all_machines["402"].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "easyrsa" { + name = "easyrsa" + + model = var.model-name + + charm { + name = "easyrsa" + channel = var.easyrsa_channel + base = var.default-base + } + + placement = juju_machine.easyrsa.machine_id + + endpoint_bindings = [{space = var.oam-space}] + + units = 1 +} + +resource "juju_integration" "vault-etcd" { + + model = var.model-name + + application { + name = juju_application.vault.name + endpoint = "etcd" + } + + application { + name = juju_application.etcd.name + endpoint = "db" + } +} + +resource "juju_integration" "etcd-easyrsa" { + + model = var.model-name + + application { + name = juju_application.etcd.name + endpoint = "certificates" + } + + application { + name = juju_application.easyrsa.name + endpoint = "client" + } +} + +resource "juju_integration" "vault-ha" { + + model = var.model-name + + application { + name = juju_application.vault.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-vault.name + endpoint = "ha" + } +} + +resource "juju_integration" "vault-mysql" { + + model = var.model-name + + application { + name = juju_application.vault.name + endpoint = "shared-db" + } + + application { + name = juju_application.vault-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "vault-ceph" { + + model = var.model-name + + application { + name = juju_application.vault.name + endpoint = "secrets" + } + + application { + name = juju_application.ceph-osd.name + endpoint = "secrets-storage" + } +} + +resource "juju_integration" "vault-db" { + + model = var.model-name + + application { + name = juju_application.vault-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} + +locals { + cert_apps = [ + "ceph-radosgw", + "cinder", + "glance", + "heat", + "keystone", + "mysql-innodb-cluster", + "neutron-api", + "neutron-api-plugin-ovn", + "nova-cloud-controller", + "openstack-dashboard", + "ovn-central", + "ovn-chassis", + "placement", + ] + +} + +resource "juju_integration" "vault-cert" { + for_each = toset(local.cert_apps) + + model = var.model-name + + application { + name = juju_application.vault.name + endpoint = "certificates" + } + + application { + name = each.value + endpoint = "certificates" + } +} + diff --git a/juju/home-maas-jammy/additional/05-ceilometer.tf b/juju/home-maas-jammy/additional/05-ceilometer.tf new file mode 100644 index 0000000..91a8347 --- /dev/null +++ b/juju/home-maas-jammy/additional/05-ceilometer.tf @@ -0,0 +1,88 @@ +resource "juju_machine" "ceilometer" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index+var.num_units]].machine_id]) + constraints = "spaces=oam" +} + +resource "juju_application" "ceilometer" { + name = "ceilometer" + + model = var.model-name + + charm { + name = "ceilometer" + channel = var.openstack-channel + } + + units = 3 + + placement = "${join(",", sort([ + for res in juju_machine.ceilometer : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "public" + space = var.public-space + },{ + endpoint = "admin" + space = var.admin-space + },{ + endpoint = "internal" + space = var.internal-space + }] + + config = { + openstack-origin = var.openstack-origin + region = var.openstack-region + use-internal-endpoints = "true" + } +} + +resource "juju_integration" "ceilometer-rmq" { + + model = var.model-name + + application { + name = juju_application.ceilometer.name + endpoint = "amqp" + } + + application { + name = juju_application.rabbitmq-server.name + endpoint = "amqp" + } +} + +resource "juju_integration" "ceilometer-keystone" { + + model = var.model-name + + application { + name = juju_application.ceilometer.name + endpoint = "identity-credentials" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-credentials" + } +} + +resource "juju_integration" "ceilometer-ceil-agent" { + + model = var.model-name + + application { + name = juju_application.ceilometer.name + endpoint = "ceilometer-service" + } + + application { + name = juju_application.ceilometer-agent.name + endpoint = "ceilometer-service" + } +} diff --git a/juju/home-maas-jammy/additional/05-cinder-purestorage.tf b/juju/home-maas-jammy/additional/05-cinder-purestorage.tf new file mode 100644 index 0000000..6dc31fd --- /dev/null +++ b/juju/home-maas-jammy/additional/05-cinder-purestorage.tf @@ -0,0 +1,46 @@ +resource "juju_application" "cinder-purestorage" { + name = "cinder-purestorage" + + model = var.model-name + + charm { + name = "cinder-purestorage" + channel = var.openstack-channel + } + + units = 0 + + config = { + driver-source: "http://${var.apt_mirror}/ppa.launchpadcontent.net/openstack-charmers/purestorage-stable/ubuntu jammy main" + driver-key = <<-EOT + -----BEGIN PGP PUBLIC KEY BLOCK----- + + mI0EUwTecAEEANePxwI2aWHW6cqp/uWMM9dHujQ76nbagdMQbTdpyV6khj6iJu5/ + 2HJXnkxY/Y6AUIOFj1R4IAmkoKhY6Gu/4NatVmDyleKwkJv8PFv2UlRJuPMlRuwy + PA/DpwCx0IPXR/co0vn1SeCEhdlJVckLTpxWzs2CSUDmoIox/8Mx3jV/ABEBAAG0 + JExhdW5jaHBhZCBQUEEgZm9yIE9wZW5TdGFjayBDaGFybWVyc4i4BBMBAgAiBQJT + BN5wAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRD+/WOfImcqefeXA/46 + mwC6Vgu5dMOn+OepZbx1fV9YtA0eni5GpcPgQbhPAkB5oUbSWSxNvlSece4HXAs1 + 9K7Mz8ktH/gDDGarPjznjhbYT8mq0YynzzLt9t9fkdpxhxhx4SmraY8Qymzr5qvB + Zek/Ak1B7Rx5cmZBRiG9I0ah5rFNB2jf4lEwWfV1ug== + =h/5S + -----END PGP PUBLIC KEY BLOCK----- + EOT + } +} + +resource "juju_integration" "cinder-pure" { + + model = var.model-name + + application { + name = juju_application.cinder.name + endpoint = "storage-backend" + } + + application { + name = juju_application.cinder-purestorage.name + endpoint = "storage-backend" + } +} + diff --git a/juju/home-maas-jammy/additional/05-gnocchi.tf b/juju/home-maas-jammy/additional/05-gnocchi.tf new file mode 100644 index 0000000..1132378 --- /dev/null +++ b/juju/home-maas-jammy/additional/05-gnocchi.tf @@ -0,0 +1,215 @@ +resource "juju_machine" "gnocchi" { + count = var.num_units + model = var.model-name + placement = join(":", ["lxd", juju_machine.all_machines[var.controller_ids[count.index+var.num_units]].machine_id]) + constraints = "spaces=oam,ceph-access" +} + +resource "juju_application" "gnocchi" { + name = "gnocchi" + + model = var.model-name + + charm { + name = "gnocchi" + channel = var.openstack-channel + } + + units = var.num_units + + placement = "${join(",", sort([ + for res in juju_machine.gnocchi : + res.machine_id + ]))}" + + endpoint_bindings = [{ + space = var.oam-space + },{ + endpoint = "public" + space = var.public-space + },{ + endpoint = "admin" + space = var.admin-space + },{ + endpoint = "internal" + space = var.internal-space + },{ + endpoint = "shared-db" + space = var.internal-space + },{ + endpoint = "storage-ceph" + space = var.ceph-public-space + },{ + endpoint = "coordinator-memcached" + space = var.internal-space + }] + + config = { + worker-multiplier = var.worker-multiplier + openstack-origin = var.openstack-origin + region = var.openstack-region + vip = var.vips["gnocchi"] + use-internal-endpoints = "true" + } +} + +resource "juju_application" "gnocchi-mysql-router" { + name = "gnocchi-mysql-router" + + model = var.model-name + + charm { + name = "mysql-router" + channel = var.mysql-router-channel + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + },{ + space = var.internal-space + endpoint = "shared-db" + },{ + space = var.internal-space + endpoint = "db-router" + }] + + config = { + source = var.openstack-origin + } +} + +resource "juju_application" "hacluster-gnocchi" { + name = "hacluster-gnocchi" + + model = var.model-name + + charm { + name = "hacluster" + channel = var.hacluster-channel + } + + units = 0 +} + +resource "juju_integration" "gnocchi-ha" { + + + model = var.model-name + + application { + name = juju_application.gnocchi.name + endpoint = "ha" + } + + application { + name = juju_application.hacluster-gnocchi.name + endpoint = "ha" + } +} + +resource "juju_integration" "gnocchi-mysql" { + + model = var.model-name + + application { + name = juju_application.gnocchi.name + endpoint = "shared-db" + } + + application { + name = juju_application.gnocchi-mysql-router.name + endpoint = "shared-db" + } +} + +resource "juju_integration" "gnocchi-db" { + + model = var.model-name + + application { + name = juju_application.gnocchi-mysql-router.name + endpoint = "db-router" + } + + application { + name = juju_application.mysql-innodb-cluster.name + endpoint = "db-router" + } +} + +resource "juju_integration" "gnocchi-rmq" { + + model = var.model-name + + application { + name = juju_application.gnocchi.name + endpoint = "amqp" + } + + application { + name = juju_application.rabbitmq-server.name + endpoint = "amqp" + } +} + +resource "juju_integration" "gnocchi-keystone" { + + model = var.model-name + + application { + name = juju_application.gnocchi.name + endpoint = "identity-service" + } + + application { + name = juju_application.keystone.name + endpoint = "identity-service" + } +} + +resource "juju_integration" "gnocchi-ceph" { + + model = var.model-name + + application { + name = juju_application.gnocchi.name + endpoint = "storage-ceph" + } + + application { + name = juju_application.ceph-mon.name + endpoint = "client" + } +} + +resource "juju_integration" "gnocchi-memcache" { + + model = var.model-name + + application { + name = juju_application.gnocchi.name + endpoint = "coordinator-memcached" + } + + application { + name = juju_application.memcached.name + endpoint = "cache" + } +} + +resource "juju_integration" "gnocchi-ceilometer" { + + model = var.model-name + + application { + name = juju_application.gnocchi.name + endpoint = "metric-service" + } + + application { + name = juju_application.ceilometer.name + endpoint = "metric-service" + } +} diff --git a/juju/home-maas-jammy/additional/06-ceilometer-agent.tf b/juju/home-maas-jammy/additional/06-ceilometer-agent.tf new file mode 100644 index 0000000..5b0b80c --- /dev/null +++ b/juju/home-maas-jammy/additional/06-ceilometer-agent.tf @@ -0,0 +1,46 @@ +resource "juju_application" "ceilometer-agent" { + name = "ceilometer-agent" + + model = var.model-name + + charm { + name = "ceilometer-agent" + channel = var.openstack-channel + } + + units = 0 + + config = { + use-internal-endpoints = "true" + } +} + +resource "juju_integration" "compute-ceilometer" { + + model = var.model-name + + application { + name = juju_application.nova-compute-kvm.name + endpoint = "nova-ceilometer" + } + + application { + name = juju_application.ceilometer-agent.name + endpoint = "nova-ceilometer" + } +} + +resource "juju_integration" "ceilometer-agent-rmq" { + + model = var.model-name + + application { + name = juju_application.ceilometer-agent.name + endpoint = "amqp" + } + + application { + name = juju_application.rabbitmq-server.name + endpoint = "amqp" + } +} diff --git a/juju/home-maas-jammy/additional/09-landscape-client.tf b/juju/home-maas-jammy/additional/09-landscape-client.tf new file mode 100644 index 0000000..fea8fe7 --- /dev/null +++ b/juju/home-maas-jammy/additional/09-landscape-client.tf @@ -0,0 +1,89 @@ +resource "juju_application" "landscape-client-bionic" { + name = "landscape-client-bionic" + + model = var.model-name + + charm { + name = "landscape-client" + channel = "latest/stable" + revision = 44 + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + }] + + config = { + account-name = "standalone" + install_sources = <<-EOF + - "deb http://${var.apt_mirror}/ppa.launchpad.net/landscape/19.10/ubuntu bionic main" + EOF + install_keys = <<-EOF + - | + -----BEGIN PGP PUBLIC KEY BLOCK----- + Version: SKS 1.1.6 + Comment: Hostname: keyserver.ubuntu.com + mI0ESXN/egEEAOgRYISU9dnQm4BB5ZEEwKT+NKUDNd/DhMYdtBMw9Yk7S5cyoqpbtwoPJVzK + AXxq+ng5e3yYypSv98pLMr5UF09FGaeyGlD4s1uaVFWkFCO4jsTg7pWIY6qzO/jMxB5+Yu/G + 0GjWQMNKxFk0oHMa0PhNBZtdPacVz65mOVmCsh/lABEBAAG0G0xhdW5jaHBhZCBQUEEgZm9y + IExhbmRzY2FwZYi2BBMBAgAgBQJJc396AhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ + boWobkZStOb+rwP+ONKUWeX+MTIPqGWkknBPV7jm8nyyIUojC4IhS+9YR6GYnn0hMABSkEHm + IV73feKmrT2GESYI1UdYeKiOkWsPN/JyBk+eTvKet0qsw5TluqiHSW+LEi/+zUyrS3dDMX3o + yaLgYa+UkjIyxnaKLkQuCiS+D+fYwnJulIkhaKObtdE= + =UwRd + -----END PGP PUBLIC KEY BLOCK----- + EOF + # registration-key = file(../secrets/landscape-registration.txt) + disable-unattended-upgrades = "true" + # the reason that this has to be done manually is because Landscape server needs an admin user to be + # created first (manual step, see above). Once the user and registration key is set configure the clients' url and ping-url options. + #ping-url = http://landscape.example.com/ping + #url = https://landscape.example.com/message-system + } +} + +resource "juju_application" "landscape-client" { + name = "landscape-client" + + model = var.model-name + + charm { + name = "landscape-client" + channel = "latest/stable" + revision = 44 + } + + units = 0 + + endpoint_bindings = [{ + space = var.oam-space + }] + + config = { + account-name = "standalone" + #registration-key = file(../secrets/landscape-registration.txt) + disable-unattended-upgrades = "true" + # the reason that this has to be done manually is because Landscape server needs an admin user to be + # created first (manual step, see above). Once the user and registration key is set configure the clients' url and ping-url options. + #ping-url = http://landscape.example.com/ping + #url = https://landscape.example.com/message-system + } +} + +resource "juju_integration" "landscape-client-integration" { + for_each = toset(var.all_services) + + model = var.model-name + + application { + name = juju_application.landscape-client.name + endpoint = "container" + } + + application { + name = "${each.value}" + endpoint = "juju-info" + } +} diff --git a/juju/home-maas-jammy/terraform.tfvars b/juju/home-maas-jammy/terraform.tfvars new file mode 100644 index 0000000..730a4b2 --- /dev/null +++ b/juju/home-maas-jammy/terraform.tfvars @@ -0,0 +1,108 @@ +model-name = "cpe-jammy" + +machines = [ + {machine_id=100,constraints="tags=control,asrock01"}, + {machine_id=101,constraints="tags=control,asrock02"}, + {machine_id=102,constraints="tags=control,asrock03"}, + {machine_id=103,constraints="tags=control,asrock04"}, + {machine_id=104,constraints="tags=control,asrock02"}, + {machine_id=105,constraints="tags=control,asrock03"}, + {machine_id=400,constraints="tags=compute,asrock01"}, + {machine_id=401,constraints="tags=compute,asrock02"}, + {machine_id=402,constraints="tags=compute,asrock03"}, + {machine_id=1000,constraints="tags=compute,asrock01"}, + {machine_id=1001,constraints="tags=compute,asrock01"}, + {machine_id=1002,constraints="tags=compute,asrock02"}, + {machine_id=1003,constraints="tags=compute,asrock02"}, + {machine_id=1004,constraints="tags=compute,asrock03"}, + {machine_id=1005,constraints="tags=compute,asrock03"}, + {machine_id=1006,constraints="tags=compute,asrock04"}, + {machine_id=1007,constraints="tags=compute,asrock04"}, +] + +osd-devices = "/dev/sdb /dev/sdc" + +nagios-context = "arif-nc01" + +ram-allocation-ratio = 1.0 +cpu-allocation-ratio = 2.0 + +oam-space = "oam" +admin-space = "oam" +public-space = "oam" +internal-space = "oam" +ceph-public-space = "ceph-access" +ceph-cluster-space = "ceph-replica" +overlay-space = "overlay" + +expected-osd-count = 12 +expected-mon-count = 3 + +ntp-source = "192.168.1.11" +external-network-cidr = "192.168.1.0/24" +external-network-gateway = "192.168.1.249" +dns-servers = "192.168.1.13" + +data-port = "br-data:ens9" +bridge-mappings = "physnet1:br-data" + +vips = { + aodh = "10.0.1.211" + cinder = "10.0.1.212" + dashboard = "10.0.1.213" + glance = "10.0.1.214" + heat = "10.0.1.215" + keystone = "10.0.1.216" + neutron-api = "10.0.1.218" + nova-cc = "10.0.1.219" + gnocchi = "10.0.1.220" + contrail = "10.0.1.221" + vault = "10.0.1.222" + placement = "10.0.1.223" + radosgw = "10.0.1.224" +} + +fqdn-pub = { + aodh = "aodh" + cinder = "cinder" + dashboard = "dashboard" + glance = "glance" + heat = "heat" + keystone = "keystone" + neutron-api = "neutron" + nova-cc = "nova" + gnocchi = "gnocchi" + vault = "vault" + placement = "placement" + radosgw = "swift" +} +fqdn-int = { + aodh = "aodh-int" + cinder = "cinder-int" + dashboard = "dashboard-int" + glance = "glance-int" + heat = "heat-int" + keystone = "keystone-int" + neutron-api = "neutron-int" + nova-cc = "nova-int" + gnocchi = "gnocchi-int" + vault = "vault-int" + placement = "placement-int" + radosgw = "swift-int" +} + +fqdn-admin = { + aodh = "aodh-int" + cinder = "cinder-int" + dashboard = "dashboard-int" + glance = "glance-int" + heat = "heat-int" + keystone = "keystone-int" + neutron-api = "neutron-int" + nova-cc = "nova-int" + gnocchi = "gnocchi-int" + vault = "vault-int" + placement = "placement-int" + radosgw = "swift-int" +} + diff --git a/juju/home-maas-jammy/user-data.yaml b/juju/home-maas-jammy/user-data.yaml new file mode 100644 index 0000000..a2a3e78 --- /dev/null +++ b/juju/home-maas-jammy/user-data.yaml @@ -0,0 +1,43 @@ +apt: + primary: + - arches: [amd64] + uri: http://192.168.1.12/archive.ubuntu.com/ubuntu +write_files: +- owner: root:root + path: /root/99-post-juju.yaml + permissions: '0644' + content: | + network: + version: 2 + ethernets: + ens3: + link-local: [] + ens4: + link-local: [] + ens5: + link-local: [] + ens6: + link-local: [] + ens7: + link-local: [] + ens8: + link-local: [] + ens9: + link-local: [] +- owner: root:root + path: /etc/systemd/network/99-default.link + permissions: '0644' + content: | + [Link] + NamePolicy=keep kernel database onboard path slot +preruncmd: + - locale-gen en_GB.UTF-8; update-locale + - "systemd-detect-virt --container && rm -rf /root/99-post-juju.yaml" + - "systemd-detect-virt --container && sudo snap remove --purge lxd" + - "! systemd-detect-virt --container && mv /root/99-post-juju.yaml /etc/netplan/99-post-juju.yaml" + - "! systemd-detect-virt --container && sudo lxc profile set default security.nesting true" + - sudo netplan apply + - "! systemd-detect-virt --container && update-initramfs -u -k all" +snap: + commands: + "00": systemctl restart snapd