Skip to content

Commit 60ae161

Browse files
feat: add ansible
1 parent 775f82e commit 60ae161

8 files changed

Lines changed: 207 additions & 20 deletions

File tree

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
grafana-config.ini
33
dashboard.yml
44
node-exporter.json
5+
playbooks/*
56
prometheus.yml
67
tfplan
78
.terraform.lock.hcl
@@ -68,3 +69,7 @@ override.tf.json
6869
# Ignore CLI configuration files
6970
.terraformrc
7071
terraform.rc
72+
73+
# INCLUDE
74+
!**/*.example
75+
!**/.gitkeep

ansible.tf

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
resource "ansible_group" "node_exporters" {
2+
name = "node_exporters"
3+
variables = {
4+
node_exporter_port = var.node_exporter_port
5+
node_exporter_image = docker_image.node_exporter.name
6+
}
7+
}
8+
9+
resource "local_file" "ansible_inventory" {
10+
filename = "${path.module}/hosts"
11+
content = "placeholder"
12+
}
13+
14+
resource "ansible_host" "node_exporter_hosts" {
15+
for_each = { for host in var.node_exporter_hosts : host.name => host }
16+
17+
name = each.value.name
18+
groups = [ansible_group.node_exporters.name]
19+
20+
variables = {
21+
ansible_host = each.value.ip
22+
ansible_user = each.value.ssh_user
23+
ansible_port = each.value.ssh_port
24+
ansible_ssh_private_key_file = var.ssh_private_key_path
25+
}
26+
}
27+
28+
resource "local_file" "node_exporter_playbook" {
29+
filename = "${path.module}/playbooks/node_exporter.yml"
30+
content = <<-EOF
31+
---
32+
- hosts: node_exporters
33+
become: true
34+
tasks:
35+
- name: Pull node-exporter image
36+
docker_image:
37+
name: "{{ node_exporter_image }}"
38+
source: pull
39+
force_source: yes
40+
41+
- name: Run node-exporter container
42+
docker_container:
43+
name: node-exporter
44+
image: "{{ node_exporter_image }}"
45+
state: started
46+
restart_policy: unless-stopped
47+
ports:
48+
- "{{ node_exporter_port }}:9100"
49+
destroy_grace_seconds: 10
50+
restart: yes
51+
force_kill: yes
52+
recreate: yes
53+
EOF
54+
}
55+
56+
resource "null_resource" "run_ansible" {
57+
depends_on = [
58+
local_file.node_exporter_playbook,
59+
ansible_host.node_exporter_hosts,
60+
ansible_group.node_exporters,
61+
local_file.ansible_inventory
62+
]
63+
64+
provisioner "local-exec" {
65+
command = "ansible-playbook -i ${path.module}/ansible_inventory ${path.module}/playbooks/node_exporter.yml"
66+
67+
environment = {
68+
ANSIBLE_HOST_KEY_CHECKING = "False"
69+
}
70+
}
71+
72+
triggers = {
73+
playbook_hash = local_file.node_exporter_playbook.content
74+
hosts_hash = jsonencode(ansible_host.node_exporter_hosts)
75+
image_hash = docker_image.node_exporter.repo_digest
76+
}
77+
}

main.tf

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ resource "docker_container" "prometheus" {
3030
name = docker_network.promgraf_network.name
3131
}
3232

33+
restart = "unless-stopped"
34+
35+
destroy_grace_seconds = 10
36+
3337
depends_on = [
3438
docker_volume.prometheus_data,
3539
local_file.prometheus_config
3640
]
37-
38-
destroy_grace_seconds = 10
3941
}
4042

4143
resource "docker_container" "grafana" {
@@ -78,6 +80,9 @@ resource "docker_container" "grafana" {
7880
networks_advanced {
7981
name = docker_network.promgraf_network.name
8082
}
83+
restart = "unless-stopped"
84+
85+
destroy_grace_seconds = 10
8186

8287
depends_on = [
8388
docker_volume.grafana_data,
@@ -87,8 +92,6 @@ resource "docker_container" "grafana" {
8792
local_file.node_exporter_dashboard,
8893
local_file.grafana_datasource
8994
]
90-
91-
destroy_grace_seconds = 10
9295
}
9396

9497
resource "local_file" "grafana_datasource" {
@@ -108,12 +111,17 @@ resource "docker_container" "node_exporter" {
108111
networks_advanced {
109112
name = docker_network.promgraf_network.name
110113
}
114+
115+
restart = "unless-stopped"
116+
117+
destroy_grace_seconds = 10
111118
}
112119

113120
resource "local_file" "prometheus_config" {
114121
content = templatefile("${path.module}/config/prometheus.yml.tpl", {
115-
prometheus_port = var.prometheus_port
116-
node_exporter_port = var.node_exporter_port
122+
prometheus_port = var.prometheus_port
123+
node_exporter_port = var.node_exporter_port
124+
node_exporter_hosts = var.node_exporter_hosts
117125
})
118126
filename = "${path.module}/config/prometheus.yml"
119127
}
@@ -141,11 +149,7 @@ resource "local_file" "node_exporter_dashboard" {
141149
}
142150

143151
resource "null_resource" "wait_for_containers" {
144-
count = length([
145-
docker_container.prometheus.id,
146-
docker_container.grafana.id,
147-
docker_container.node_exporter.id
148-
])
152+
count = 1
149153

150154
depends_on = [
151155
docker_container.prometheus,
@@ -157,3 +161,13 @@ resource "null_resource" "wait_for_containers" {
157161
command = "sleep 10"
158162
}
159163
}
164+
165+
resource "null_resource" "wait_for_remote_containers" {
166+
depends_on = [
167+
null_resource.run_ansible
168+
]
169+
170+
provisioner "local-exec" {
171+
command = "sleep 10"
172+
}
173+
}

outputs.tf

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,71 @@
1-
# output "output" {
2-
# value = terraform_data.this.output
3-
# description = "This is an example of an output."
4-
# }
1+
# Prometheus outputs
2+
output "prometheus_url" {
3+
description = "URL to access Prometheus UI"
4+
value = "http://localhost:${var.prometheus_port}"
5+
}
6+
7+
output "prometheus_container_id" {
8+
description = "ID of the Prometheus container"
9+
value = docker_container.prometheus.id
10+
}
11+
12+
# Grafana outputs
13+
output "grafana_url" {
14+
description = "URL to access Grafana UI"
15+
value = "http://localhost:${var.grafana_port}"
16+
}
17+
18+
output "grafana_container_id" {
19+
description = "ID of the Grafana container"
20+
value = docker_container.grafana.id
21+
}
22+
23+
output "grafana_credentials" {
24+
description = "Grafana login credentials"
25+
value = {
26+
username = var.grafana_admin_user
27+
password = nonsensitive(var.grafana_admin_password) # Mark as non-sensitive for output
28+
}
29+
sensitive = true
30+
}
31+
32+
# Node Exporter outputs
33+
output "local_node_exporter" {
34+
description = "Local node-exporter details"
35+
value = {
36+
url = "http://localhost:${var.node_exporter_port}/metrics"
37+
container_id = docker_container.node_exporter.id
38+
network = docker_network.promgraf_network.name
39+
}
40+
}
41+
42+
output "remote_node_exporters" {
43+
description = "Remote node-exporter details"
44+
value = {
45+
for host in var.node_exporter_hosts : host.name => {
46+
url = "http://${host.ip}:${var.node_exporter_port}/metrics"
47+
host = host.ip
48+
ssh_user = host.ssh_user
49+
}
50+
}
51+
}
52+
53+
# Network info
54+
output "monitoring_network" {
55+
description = "Docker network details"
56+
value = {
57+
name = docker_network.promgraf_network.name
58+
id = docker_network.promgraf_network.id
59+
}
60+
}
61+
62+
# Configuration files
63+
output "config_files" {
64+
description = "Paths to important configuration files"
65+
value = {
66+
prometheus_config = local_file.prometheus_config.filename
67+
grafana_config = local_file.grafana_config.filename
68+
dashboards_path = "${path.module}/config/grafana/dashboards"
69+
datasources_path = "${path.module}/config/grafana/provisioning/datasources"
70+
}
71+
}

playbooks/.gitkeep

Whitespace-only changes.

providers.tf

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ terraform {
44
source = "kreuzwerker/docker"
55
version = "~> 3.0.2"
66
}
7+
ansible = {
8+
source = "ansible/ansible"
9+
version = "~> 1.3.0"
10+
}
711
}
812
}
913

@@ -13,8 +17,6 @@ provider "docker" {
1317
address = "https://index.docker.io/v1/"
1418
config_file = pathexpand("~/.docker/config.json")
1519
}
16-
registry_auth {
17-
address = "ghcr.io"
18-
config_file = pathexpand("~/.docker/config.json")
19-
}
2020
}
21+
22+
provider "ansible" {}

resources.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ resource "docker_image" "grafana" {
2121
}
2222

2323
resource "docker_image" "node_exporter" {
24-
name = "prom/node-exporter:latest"
24+
name = "prom/node-exporter:latest"
25+
keep_locally = true
2526
}
2627

variables.tf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ variable "node_exporter_port" {
1313
default = 9100
1414
}
1515

16+
variable "node_exporter_hosts" {
17+
description = "List of hosts for node-exporter deployment"
18+
type = list(object({
19+
name = string
20+
ip = string
21+
ssh_user = string
22+
ssh_port = number
23+
}))
24+
}
25+
1626
variable "grafana_admin_user" {
1727
description = "The Grafana admin username"
1828
default = "admin"
@@ -28,3 +38,14 @@ variable "grafana_datasource_name" {
2838
type = string
2939
default = "Prometheus"
3040
}
41+
42+
variable "ssh_private_key_path" {
43+
description = "Path to SSH private key for Ansible"
44+
type = string
45+
}
46+
47+
variable "ssh_port" {
48+
description = "SSH port for Ansible connections"
49+
type = number
50+
default = 22
51+
}

0 commit comments

Comments
 (0)