From 04edbb0d4e22d308cf7a8755a939f0882e67fc5f Mon Sep 17 00:00:00 2001 From: Kalibh Halford Date: Wed, 20 Aug 2025 09:19:58 +0100 Subject: [PATCH] MAINT: Reduce terraform provisioning to a single VM We do not need a VM for each service when we can run all services on a single VM. This reduces the scale and complexity of the deployment. There is not enough traffic to justify having this much compute resource. --- chatops_deployment/ansible/configure.yml | 16 +- .../roles/elastic/templates/kibana.yml.j2 | 2 +- .../roles/grafana/templates/grafana.ini.j2 | 2 +- .../roles/ssh_known_hosts/tasks/main.yml | 77 ++------- .../ansible/roles/terraform/tasks/destroy.yml | 13 -- .../terraform/templates/terraform.tfvars.j2 | 3 +- chatops_deployment/terraform/main.tf | 8 +- .../terraform/modules/compute/main.tf | 78 ++------- .../terraform/modules/compute/outputs.tf | 24 +-- .../terraform/modules/compute/variables.tf | 8 +- .../terraform/modules/networking/main.tf | 154 +----------------- .../terraform/modules/networking/outputs.tf | 20 +-- chatops_deployment/terraform/outputs.tf | 27 +-- chatops_deployment/terraform/variables.tf | 4 +- 14 files changed, 61 insertions(+), 375 deletions(-) diff --git a/chatops_deployment/ansible/configure.yml b/chatops_deployment/ansible/configure.yml index bd3fab15..f323a6d1 100644 --- a/chatops_deployment/ansible/configure.yml +++ b/chatops_deployment/ansible/configure.yml @@ -1,20 +1,20 @@ --- - name: Configure load balancer - hosts: haproxy + hosts: stack roles: - role: haproxy tags: - haproxy - name: Configure ChatOps - hosts: chatops + hosts: stack roles: - role: chatops tags: - chatops - name: Configure CAdvisor - hosts: chatops + hosts: stack remote_user: ubuntu roles: - role: cadvisor @@ -22,35 +22,35 @@ - cadvisor - name: Set up systemd exporters - hosts: all + hosts: stack roles: - role: systemd_exporter tags: - systemd_exporter - name: Configure Grafana - hosts: grafana + hosts: stack roles: - grafana tags: - grafana - name: Configure Prometheus - hosts: prometheus + hosts: stack roles: - prometheus tags: - prometheus - name: Configure Alert Manager - hosts: prometheus + hosts: stack roles: - alertmanager tags: - alertmanager - name: Configure Elastic Stack - hosts: elastic + hosts: stack remote_user: ubuntu force_handlers: true roles: diff --git a/chatops_deployment/ansible/roles/elastic/templates/kibana.yml.j2 b/chatops_deployment/ansible/roles/elastic/templates/kibana.yml.j2 index 0241566f..56e93158 100644 --- a/chatops_deployment/ansible/roles/elastic/templates/kibana.yml.j2 +++ b/chatops_deployment/ansible/roles/elastic/templates/kibana.yml.j2 @@ -1,4 +1,4 @@ -server.host: {{ inventory_hostname }} +server.host: localhost server.port: 5601 server.publicBaseUrl: https://kibana.{{ domain }}:443 elasticsearch.hosts: ["https://localhost:9200"] diff --git a/chatops_deployment/ansible/roles/grafana/templates/grafana.ini.j2 b/chatops_deployment/ansible/roles/grafana/templates/grafana.ini.j2 index c2032d12..29c92eb9 100644 --- a/chatops_deployment/ansible/roles/grafana/templates/grafana.ini.j2 +++ b/chatops_deployment/ansible/roles/grafana/templates/grafana.ini.j2 @@ -2,7 +2,7 @@ # Configure server settings domain = grafana.{{ domain }} root_url = https://grafana.{{ domain }}:443/ -http_addr = {{ inventory_hostname }} +http_addr = 127.0.0.1 protocol = http http_port = 3000 diff --git a/chatops_deployment/ansible/roles/ssh_known_hosts/tasks/main.yml b/chatops_deployment/ansible/roles/ssh_known_hosts/tasks/main.yml index 391580d4..53385a0f 100644 --- a/chatops_deployment/ansible/roles/ssh_known_hosts/tasks/main.yml +++ b/chatops_deployment/ansible/roles/ssh_known_hosts/tasks/main.yml @@ -2,66 +2,23 @@ - name: Refresh inventory to grab latest changes ansible.builtin.meta: refresh_inventory -- name: Add ssh key to agent - block: - - name: Install expect - become: true - ansible.builtin.apt: - name: expect - update_cache: true - - - name: Add key to ssh-agent - ansible.builtin.command: | - expect << EOF - spawn ssh-add bastion-key - expect "Enter passphrase for bastion-key:" - send "{{ bastion_key_passphrase }}\r" - expect eof - EOF - register: ssh_known_hosts_ - changed_when: ssh_known_hosts_.rc != 0 - -- name: Remove FIP known hosts - ansible.builtin.command: 'ssh-keygen -R "{{ terraform_floating_ip }}"' - register: ssh_known_hosts_ - changed_when: ssh_known_hosts_.rc != 0 +- name: Remove FIP from known hosts + ansible.builtin.known_hosts: + name: "{{ item }}" + state: absent + loop: + - "{{ terraform_floating_ip }}" + - "{{ domain }}" -- name: Remove private VM known host entries - ansible.builtin.command: "ssh-keygen -R {{ item }}" - loop: "{{ groups['private'] }}" - register: ssh_known_hosts_ - changed_when: ssh_known_hosts_.rc != 0 +- name: Wait for VMs to be ready + ansible.builtin.wait_for: + timeout: 10 - name: Add FIP fingerprint to known hosts - ansible.builtin.command: 'ssh-keyscan "{{ terraform_floating_ip }}" >> ~/.ssh/known_hosts' - register: ssh_known_hosts_ - changed_when: ssh_known_hosts_.rc != 0 - -- name: Get private VM fingerprints and retrieve to local host - delegate_to: "{{ terraform_floating_ip }}" - block: - - name: Add private VM fingerprints to known hosts on LB - ansible.builtin.command: 'ssh-keyscan "{{ item }}" >> ~/.ssh/known_hosts' - loop: "{{ groups['private'] }}" - register: ssh_known_hosts_ - changed_when: ssh_known_hosts_.rc != 0 - - - name: Retrieve known hosts from LB - ansible.builtin.fetch: - src: "~/.ssh/known_hosts" - dest: "private_known_hosts.tmp" - flat: true - register: ssh_known_hosts_ - changed_when: ssh_known_hosts_.rc != 0 - -- name: Append fetched known hosts to localhost - ansible.builtin.command: "cat private_known_hosts.tmp >> ~/.ssh/known_hosts" - register: ssh_known_hosts_ - changed_when: ssh_known_hosts_.rc != 0 - -- name: Remove private_known_hosts.tmp - ansible.builtin.file: - path: "private_known_hosts.tmp" - state: absent - register: ssh_known_hosts_ - changed_when: ssh_known_hosts_.rc != 0 + ansible.builtin.known_hosts: + name: "{{ item }}" + state: present + key: "{{ lookup('ansible.builtin.pipe', 'ssh-keyscan {{ item }}') }}" + loop: + - "{{ terraform_floating_ip }}" + - "{{ domain }}" diff --git a/chatops_deployment/ansible/roles/terraform/tasks/destroy.yml b/chatops_deployment/ansible/roles/terraform/tasks/destroy.yml index 08f9398d..5d5526a4 100644 --- a/chatops_deployment/ansible/roles/terraform/tasks/destroy.yml +++ b/chatops_deployment/ansible/roles/terraform/tasks/destroy.yml @@ -19,19 +19,6 @@ - name: Remove generated files block: - - name: Delete hosts.ini file - ansible.builtin.file: - path: hosts.ini - state: absent - - - name: Touch hosts.ini file - ansible.builtin.file: - path: hosts.ini - state: touch - owner: "{{ ansible_env.USER }}" - group: "{{ ansible_env.USER }}" - mode: "0774" - - name: Delete terraform.tfvars file ansible.builtin.file: path: "../terraform/terraform.tfvars" diff --git a/chatops_deployment/ansible/roles/terraform/templates/terraform.tfvars.j2 b/chatops_deployment/ansible/roles/terraform/templates/terraform.tfvars.j2 index f9372241..5278f97e 100644 --- a/chatops_deployment/ansible/roles/terraform/templates/terraform.tfvars.j2 +++ b/chatops_deployment/ansible/roles/terraform/templates/terraform.tfvars.j2 @@ -1,4 +1,5 @@ deployment="{{ terraform_deployment }}" external_network_id="{{ terraform_external_network_id }}" floating_ip="{{ terraform_floating_ip }}" -elasticsearch_volume_id="{{ terraform_elasticsearch_volume_id }}" \ No newline at end of file +stack_volume_id="{{ terraform_stack_volume_id }}" +environment="{{ env }}" \ No newline at end of file diff --git a/chatops_deployment/terraform/main.tf b/chatops_deployment/terraform/main.tf index e6c5dd66..1c320d31 100644 --- a/chatops_deployment/terraform/main.tf +++ b/chatops_deployment/terraform/main.tf @@ -21,14 +21,10 @@ module "networking" { module "compute" { source = "./modules/compute" - grafana_secgroup = module.networking.grafana_secgroup - chatops_secgroup = module.networking.chatops_secgroup - prometheus_secgroup = module.networking.prometheus_secgroup - elasticsearch_secgroup = module.networking.elasticsearch_secgroup - loadbalancer_secgroup = module.networking.loadbalancer_secgroup + stack_secgroup = module.networking.stack_secgroup private_network = module.networking.private_network private_subnet = module.networking.private_subnet floating_ip = var.floating_ip deployment = var.deployment - elasticsearch_volume_id = var.elasticsearch_volume_id + stack_volume_id = var.stack_volume_id } \ No newline at end of file diff --git a/chatops_deployment/terraform/modules/compute/main.tf b/chatops_deployment/terraform/modules/compute/main.tf index ff1b11c4..35ec7015 100644 --- a/chatops_deployment/terraform/modules/compute/main.tf +++ b/chatops_deployment/terraform/modules/compute/main.tf @@ -17,85 +17,33 @@ resource "openstack_compute_keypair_v2" "bastion_keypair" { public_key = file("bastion-key.pub") } -resource "openstack_compute_instance_v2" "grafana" { - name = "grafana-host-${var.deployment}" +resource "openstack_compute_instance_v2" "stack" { + name = "chatops-stack-${var.deployment}" image_name = "ubuntu-jammy-22.04-nogui" - flavor_name = "l3.nano" + flavor_name = "l3.micro" key_pair = openstack_compute_keypair_v2.bastion_keypair.name - security_groups = ["default", var.grafana_secgroup.name] - count = 2 + security_groups = ["default", var.stack_secgroup.name] network { name = var.private_network.name + fixed_ip_v4 = "192.168.100.100" } - depends_on = [var.private_subnet] -} - -resource "openstack_compute_instance_v2" "prometheus" { - name = "prometheus-host-${var.deployment}" - image_name = "ubuntu-jammy-22.04-nogui" - flavor_name = "l3.nano" - key_pair = openstack_compute_keypair_v2.bastion_keypair.name - security_groups = ["default", var.prometheus_secgroup.name] - - network { - name = var.private_network.name - } - depends_on = [var.private_subnet] -} - -resource "openstack_compute_instance_v2" "elastic" { - name = "elasticsearch-host-${var.deployment}" - image_name = "ubuntu-jammy-22.04-nogui" - flavor_name = "l3.tiny" - key_pair = openstack_compute_keypair_v2.bastion_keypair.name - security_groups = ["default", var.elasticsearch_secgroup.name] - network { - name = var.private_network.name - } depends_on = [var.private_subnet] } -resource "openstack_compute_volume_attach_v2" "elasticsearch_volume" { - instance_id = openstack_compute_instance_v2.elastic.id - volume_id = var.elasticsearch_volume_id -} - -resource "openstack_compute_instance_v2" "chatops" { - name = "chatops-host-${var.deployment}" - image_name = "ubuntu-jammy-22.04-nogui" - flavor_name = "l3.nano" - key_pair = openstack_compute_keypair_v2.bastion_keypair.name - security_groups = ["default", var.chatops_secgroup.name] - count = 3 - - network { - name = var.private_network.name - } - depends_on = [var.private_subnet] -} - -resource "openstack_compute_instance_v2" "loadbalancer" { - name = "loadbalancer-host-${var.deployment}" - image_name = "ubuntu-jammy-22.04-nogui" - flavor_name = "l3.nano" - key_pair = openstack_compute_keypair_v2.bastion_keypair.name - security_groups = ["default", var.loadbalancer_secgroup.name] - - network { - name = var.private_network.name - } - depends_on = [var.private_subnet] +resource "openstack_compute_volume_attach_v2" "stack_volume" { + instance_id = openstack_compute_instance_v2.stack.id + volume_id = var.stack_volume_id } -data "openstack_networking_port_v2" "loadbalancer_port" { - fixed_ip = openstack_compute_instance_v2.loadbalancer.network[0].fixed_ip_v4 - network_id = openstack_compute_instance_v2.loadbalancer.network[0].uuid +data "openstack_networking_port_v2" "stack_port" { + fixed_ip = openstack_compute_instance_v2.stack.network[0].fixed_ip_v4 + network_id = openstack_compute_instance_v2.stack.network[0].uuid } resource "openstack_networking_floatingip_associate_v2" "floating_ip" { floating_ip = var.floating_ip - port_id = data.openstack_networking_port_v2.loadbalancer_port.id - depends_on = [openstack_compute_instance_v2.loadbalancer] + port_id = data.openstack_networking_port_v2.stack_port.id + depends_on = [openstack_compute_instance_v2.stack] } diff --git a/chatops_deployment/terraform/modules/compute/outputs.tf b/chatops_deployment/terraform/modules/compute/outputs.tf index 9ab4d174..305abd79 100644 --- a/chatops_deployment/terraform/modules/compute/outputs.tf +++ b/chatops_deployment/terraform/modules/compute/outputs.tf @@ -1,23 +1,3 @@ -output "grafana_host_ips" { - value = openstack_compute_instance_v2.grafana.*.access_ip_v4 +output "stack_volume_device" { + value = openstack_compute_volume_attach_v2.stack_volume.device } - -output "chatops_host_ips" { - value = openstack_compute_instance_v2.chatops.*.access_ip_v4 -} - -output "prometheus_host_ips" { - value = openstack_compute_instance_v2.prometheus.*.access_ip_v4 -} - -output "elastic_host_ips" { - value = openstack_compute_instance_v2.elastic.*.access_ip_v4 -} - -output "loadbalancer_host_ip" { - value = openstack_compute_instance_v2.loadbalancer.access_ip_v4 -} - -output "elasticsearch_device" { - value = openstack_compute_volume_attach_v2.elasticsearch_volume.device -} \ No newline at end of file diff --git a/chatops_deployment/terraform/modules/compute/variables.tf b/chatops_deployment/terraform/modules/compute/variables.tf index 5012aa4d..363614cf 100644 --- a/chatops_deployment/terraform/modules/compute/variables.tf +++ b/chatops_deployment/terraform/modules/compute/variables.tf @@ -1,10 +1,6 @@ variable "deployment" {} -variable "grafana_secgroup" {} -variable "chatops_secgroup" {} -variable "prometheus_secgroup" {} -variable "elasticsearch_secgroup" {} -variable "loadbalancer_secgroup" {} variable "private_network" {} variable "floating_ip" {} variable "private_subnet" {} -variable "elasticsearch_volume_id" {} \ No newline at end of file +variable "stack_volume_id" {} +variable "stack_secgroup" {} \ No newline at end of file diff --git a/chatops_deployment/terraform/modules/networking/main.tf b/chatops_deployment/terraform/modules/networking/main.tf index f80e9ad9..249800d9 100644 --- a/chatops_deployment/terraform/modules/networking/main.tf +++ b/chatops_deployment/terraform/modules/networking/main.tf @@ -35,167 +35,27 @@ resource "openstack_networking_router_interface_v2" "router_interface" { subnet_id = openstack_networking_subnet_v2.subnet.id } -resource "openstack_networking_secgroup_v2" "grafana" { - name = "grafana-${var.deployment}" - description = "Grafana host security group." +resource "openstack_networking_secgroup_v2" "stack" { + name = "chatops-stack-${var.deployment}" + description = "ChatOps Stack host security group." } -resource "openstack_networking_secgroup_rule_v2" "grafana" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 3000 - port_range_max = 3000 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.grafana.id -} - -resource "openstack_networking_secgroup_v2" "chatops" { - name = "chatops-${var.deployment}" - description = "ChatOps host security group." -} - -resource "openstack_networking_secgroup_rule_v2" "chatops" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 3000 - port_range_max = 3000 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.chatops.id -} - -resource "openstack_networking_secgroup_rule_v2" "cadvisor" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 8080 - port_range_max = 8080 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.chatops.id -} - -resource "openstack_networking_secgroup_v2" "prometheus" { - name = "prometheus-${var.deployment}" - description = "Prometheus host security group." -} - -resource "openstack_networking_secgroup_rule_v2" "prometheus" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 9090 - port_range_max = 9090 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.prometheus.id -} - -resource "openstack_networking_secgroup_v2" "elasticsearch" { - name = "elasticsearch-${var.deployment}" - description = "ElasticSearch host security group." -} - -resource "openstack_networking_secgroup_rule_v2" "logstash" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 5044 - port_range_max = 5044 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.elasticsearch.id -} - -resource "openstack_networking_secgroup_rule_v2" "kibana" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 5601 - port_range_max = 5601 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.elasticsearch.id -} - -resource "openstack_networking_secgroup_rule_v2" "alertmanager" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 9093 - port_range_max = 9093 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.prometheus.id -} - -resource "openstack_networking_secgroup_v2" "loadbalancer" { - name = "loadbalancer-${var.deployment}" - description = "Load balancer host security group." -} - -resource "openstack_networking_secgroup_rule_v2" "loadbalancer_http" { +resource "openstack_networking_secgroup_rule_v2" "stack_http" { direction = "ingress" ethertype = "IPv4" protocol = "tcp" port_range_min = 80 port_range_max = 80 remote_ip_prefix = "0.0.0.0/0" - security_group_id = openstack_networking_secgroup_v2.loadbalancer.id + security_group_id = openstack_networking_secgroup_v2.stack.id } -resource "openstack_networking_secgroup_rule_v2" "loadbalancer_https" { +resource "openstack_networking_secgroup_rule_v2" "stack_https" { direction = "ingress" ethertype = "IPv4" protocol = "tcp" port_range_min = 443 port_range_max = 443 remote_ip_prefix = "0.0.0.0/0" - security_group_id = openstack_networking_secgroup_v2.loadbalancer.id + security_group_id = openstack_networking_secgroup_v2.stack.id } - -resource "openstack_networking_secgroup_rule_v2" "loadbalancer_prometheus" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 8405 - port_range_max = 8405 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.loadbalancer.id -} - -resource "openstack_networking_secgroup_rule_v2" "systemd_exporter_prometheus" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 9558 - port_range_max = 9558 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.prometheus.id -} - -resource "openstack_networking_secgroup_rule_v2" "systemd_exporter_chatops" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 9558 - port_range_max = 9558 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.chatops.id -} - -resource "openstack_networking_secgroup_rule_v2" "systemd_exporter_grafana" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 9558 - port_range_max = 9558 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.grafana.id -} - -resource "openstack_networking_secgroup_rule_v2" "systemd_exporter_loadbalancer" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 9558 - port_range_max = 9558 - remote_ip_prefix = "192.168.100.0/22" - security_group_id = openstack_networking_secgroup_v2.loadbalancer.id -} \ No newline at end of file diff --git a/chatops_deployment/terraform/modules/networking/outputs.tf b/chatops_deployment/terraform/modules/networking/outputs.tf index cbfbc96b..520e658d 100644 --- a/chatops_deployment/terraform/modules/networking/outputs.tf +++ b/chatops_deployment/terraform/modules/networking/outputs.tf @@ -1,21 +1,5 @@ -output "grafana_secgroup" { - value = openstack_networking_secgroup_v2.grafana -} - -output "chatops_secgroup" { - value = openstack_networking_secgroup_v2.chatops -} - -output "prometheus_secgroup" { - value = openstack_networking_secgroup_v2.prometheus -} - -output "elasticsearch_secgroup" { - value = openstack_networking_secgroup_v2.elasticsearch -} - -output "loadbalancer_secgroup" { - value = openstack_networking_secgroup_v2.loadbalancer +output "stack_secgroup" { + value = openstack_networking_secgroup_v2.stack } output "private_network" { diff --git a/chatops_deployment/terraform/outputs.tf b/chatops_deployment/terraform/outputs.tf index 364620f5..e0f0f286 100644 --- a/chatops_deployment/terraform/outputs.tf +++ b/chatops_deployment/terraform/outputs.tf @@ -1,26 +1,3 @@ -output "grafana_host_ips" { - value = module.compute.grafana_host_ips +output "stack_volume_device" { + value = module.compute.stack_volume_device } - -output "chatops_host_ips" { - value = module.compute.chatops_host_ips -} - -output "prometheus_host_ips" { - value = module.compute.prometheus_host_ips -} -output "elastic_host_ips" { - value = module.compute.elastic_host_ips -} - -output "loadbalancer_host_ips" { - value = var.floating_ip -} - -output "loadbalancer_private_ip" { - value = module.compute.loadbalancer_host_ip -} - -output "elasticsearch_device" { - value = module.compute.elasticsearch_device -} \ No newline at end of file diff --git a/chatops_deployment/terraform/variables.tf b/chatops_deployment/terraform/variables.tf index 6cb147a6..c210e9be 100644 --- a/chatops_deployment/terraform/variables.tf +++ b/chatops_deployment/terraform/variables.tf @@ -13,7 +13,7 @@ variable "external_network_id" { description = "ID of the external network in your project." } -variable "elasticsearch_volume_id" { +variable "stack_volume_id" { type = string - description = "ID of the elasticsearch volume in your project." + description = "ID of the ChatOps Stack volume in your project." }