Terraofrm module to deploy cloudwatch_exporter on kubernetes.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
7.3KB

  1. #####
  2. # Locals
  3. #####
  4. locals {
  5. labels = {
  6. "app.kubernetes.io/version" = var.image_version
  7. "app.kubernetes.io/component" = "exporter"
  8. "app.kubernetes.io/part-of" = "monitoring"
  9. "app.kubernetes.io/managed-by" = "terraform"
  10. "app.kubernetes.io/name" = "cloudwatch-exporter"
  11. }
  12. configuration = yamlencode(var.configuration)
  13. port = 9106
  14. service_port = 80
  15. prometheus_alert_groups = [
  16. {
  17. "name" = "cloudwatch-exporter"
  18. "rules" = [
  19. {
  20. "alert" = "CloudwatchExporterScrapeErrors"
  21. "expr" = "cloudwatch_exporter_scrape_error > 0"
  22. "for" = "1m"
  23. "labels" = merge(
  24. {
  25. "severity" = "critical"
  26. "urgency" = "2"
  27. },
  28. var.prometheus_alert_groups_rules_labels
  29. )
  30. "annotations" = merge(
  31. {
  32. "summary" = "Cloudwatch Exporter - Scrape Error on {{ $labels.instance }}",
  33. "description" = "Cloudwatch Exporter: \n {{ $labels.instance }} scrape error.\nLabels:\n{{ $labels }}"
  34. },
  35. var.prometheus_alert_groups_rules_annotations
  36. )
  37. },
  38. {
  39. "alert" = "CloudwatchExporterScrapeDurationError"
  40. "expr" = "deriv(cloudwatch_exporter_last_scrape_duration_seconds[2m]) > 0.2 and cloudwatch_exporter_last_scrape_duration_seconds > 10"
  41. "for" = "5m"
  42. "labels" = merge(
  43. {
  44. "severity" = "warning"
  45. "urgency" = "3"
  46. },
  47. var.prometheus_alert_groups_rules_labels
  48. )
  49. "annotations" = merge(
  50. {
  51. "summary" = "Cloudwatch Exporter - Scrape Duration Error on {{ $labels.instance }}",
  52. "description" = "Cloudwatch Exporter:\n {{ $labels.instance }} scrape duration is too high.\nLabels:\n{{ $labels }}"
  53. },
  54. var.prometheus_alert_groups_rules_annotations
  55. )
  56. }
  57. ]
  58. }
  59. ]
  60. }
  61. #####
  62. # Randoms
  63. #####
  64. resource "random_string" "selector" {
  65. special = false
  66. upper = false
  67. number = false
  68. length = 8
  69. }
  70. #####
  71. # Deployment
  72. #####
  73. resource "kubernetes_deployment" "this" {
  74. count = var.enabled ? 1 : 0
  75. metadata {
  76. name = var.deployment_name
  77. namespace = var.namespace
  78. annotations = merge(
  79. var.annotations,
  80. var.deployment_annotations
  81. )
  82. labels = merge(
  83. {
  84. "app.kubernetes.io/instance" = var.deployment_name
  85. },
  86. local.labels,
  87. var.labels,
  88. var.deployment_labels
  89. )
  90. }
  91. spec {
  92. replicas = 1
  93. selector {
  94. match_labels = {
  95. app = "cloudwatch-exporter"
  96. random = random_string.selector.result
  97. }
  98. }
  99. template {
  100. metadata {
  101. annotations = merge(
  102. {
  103. "configuration/hash" = sha256(local.configuration)
  104. },
  105. var.annotations,
  106. var.deployment_template_annotations
  107. )
  108. labels = merge(
  109. {
  110. "app.kubernetes.io/instance" = var.deployment_name
  111. app = "cloudwatch-exporter"
  112. random = random_string.selector.result
  113. },
  114. local.labels,
  115. var.labels,
  116. var.deployment_template_labels
  117. )
  118. }
  119. spec {
  120. container {
  121. name = "cloudwatch-exporter"
  122. image = "${var.image_name}:${var.image_version}"
  123. image_pull_policy = var.image_pull_policy
  124. env {
  125. name = "AWS_ACCESS_KEY_ID"
  126. value_from {
  127. secret_key_ref {
  128. name = element(concat(kubernetes_secret.this.*.metadata.0.name, [""]), 0)
  129. key = "access_key"
  130. }
  131. }
  132. }
  133. env {
  134. name = "AWS_SECRET_ACCESS_KEY"
  135. value_from {
  136. secret_key_ref {
  137. name = element(concat(kubernetes_secret.this.*.metadata.0.name, [""]), 0)
  138. key = "secret_key"
  139. }
  140. }
  141. }
  142. readiness_probe {
  143. http_get {
  144. path = "/"
  145. port = local.port
  146. scheme = "HTTP"
  147. }
  148. timeout_seconds = 5
  149. period_seconds = 10
  150. success_threshold = 1
  151. failure_threshold = 20
  152. initial_delay_seconds = 90
  153. }
  154. liveness_probe {
  155. http_get {
  156. path = "/"
  157. port = local.port
  158. scheme = "HTTP"
  159. }
  160. timeout_seconds = 5
  161. period_seconds = 10
  162. success_threshold = 1
  163. failure_threshold = 3
  164. initial_delay_seconds = 300
  165. }
  166. port {
  167. name = "http"
  168. container_port = local.port
  169. protocol = "TCP"
  170. }
  171. resources {
  172. requests {
  173. memory = "256Mi"
  174. cpu = "300m"
  175. }
  176. limits {
  177. memory = "512Mi"
  178. cpu = "500m"
  179. }
  180. }
  181. volume_mount {
  182. name = "configuration"
  183. mount_path = "/config/config.yml"
  184. sub_path = "config.yml"
  185. }
  186. }
  187. volume {
  188. name = "configuration"
  189. config_map {
  190. name = element(concat(kubernetes_config_map.this.*.metadata.0.name, [""]), 0)
  191. items {
  192. key = "config.yml"
  193. path = "config.yml"
  194. }
  195. }
  196. }
  197. }
  198. }
  199. }
  200. }
  201. #####
  202. # Secret
  203. #####
  204. resource "kubernetes_secret" "this" {
  205. count = var.enabled ? 1 : 0
  206. metadata {
  207. name = var.secret_name
  208. namespace = var.namespace
  209. annotations = merge(
  210. var.annotations,
  211. var.secret_annotations
  212. )
  213. labels = merge(
  214. {
  215. "app.kubernetes.io/instance" = var.secret_name
  216. },
  217. local.labels,
  218. var.labels,
  219. var.secret_labels
  220. )
  221. }
  222. data = {
  223. access_key = var.access_key
  224. secret_key = var.secret_key
  225. }
  226. type = "Opaque"
  227. }
  228. #####
  229. # Service
  230. #####
  231. resource "kubernetes_service" "this" {
  232. count = var.enabled ? 1 : 0
  233. metadata {
  234. name = var.service_name
  235. namespace = var.namespace
  236. annotations = merge(
  237. {
  238. "prometheus.io/scrape" = "true"
  239. },
  240. var.annotations,
  241. var.service_annotations
  242. )
  243. labels = merge(
  244. {
  245. "app.kubernetes.io/instance" = var.service_name
  246. },
  247. local.labels,
  248. var.labels,
  249. var.service_labels
  250. )
  251. }
  252. spec {
  253. selector = {
  254. random = random_string.selector.result
  255. app = "cloudwatch-exporter"
  256. }
  257. type = "ClusterIP"
  258. port {
  259. port = local.service_port
  260. target_port = "http"
  261. protocol = "TCP"
  262. name = "http"
  263. }
  264. }
  265. }
  266. #####
  267. # ConfigMap
  268. #####
  269. resource "kubernetes_config_map" "this" {
  270. count = var.enabled ? 1 : 0
  271. metadata {
  272. name = var.config_map_name
  273. namespace = var.namespace
  274. annotations = merge(
  275. var.annotations,
  276. var.config_map_annotations
  277. )
  278. labels = merge(
  279. {
  280. "app.kubernetes.io/instance" = var.config_map_name
  281. },
  282. local.labels,
  283. var.labels,
  284. var.config_map_labels
  285. )
  286. }
  287. data = {
  288. "config.yml" = local.configuration
  289. }
  290. }