@@ -0,0 +1,27 @@ | |||
# ---> Terraform | |||
# Local .terraform directories | |||
**/.terraform/* | |||
# .tfstate files | |||
*.tfstate | |||
*.tfstate.* | |||
# Crash log files | |||
crash.log | |||
# Ignore any .tfvars files that are generated automatically for each Terraform run. Most | |||
# .tfvars files are managed as part of configuration and so should be included in | |||
# version control. | |||
# | |||
# example.tfvars | |||
# Ignore override files as they are usually used to override resources locally and so | |||
# are not checked in | |||
override.tf | |||
override.tf.json | |||
*_override.tf | |||
*_override.tf.json | |||
# Include override files you do wish to add to version control using negated pattern | |||
# | |||
# !example_override.tf |
@@ -0,0 +1,14 @@ | |||
repos: | |||
- repo: git://github.com/antonbabenko/pre-commit-terraform | |||
rev: v1.24.0 | |||
hooks: | |||
- id: terraform_fmt | |||
- id: terraform_docs | |||
- repo: git://github.com/pre-commit/pre-commit-hooks | |||
rev: v2.1.0 | |||
hooks: | |||
- id: check-merge-conflict | |||
- id: trailing-whitespace | |||
- id: end-of-file-fixer | |||
- id: check-added-large-files | |||
- id: detect-private-key |
@@ -0,0 +1 @@ | |||
Christophe van de Kerchove <christophe.vkerchove@fxinnovation.com> |
@@ -0,0 +1,5 @@ | |||
0.1.0 / 2020-02-07 | |||
================== | |||
* feat: initial version of the module |
@@ -0,0 +1,28 @@ | |||
withCredentials( | |||
[ | |||
usernamePassword( | |||
credentialsId: 'azure-fxinnovation-application', | |||
passwordVariable: 'client_secret', | |||
usernameVariable: 'client_id' | |||
), | |||
] | |||
){ | |||
fxTerraformWithUsernamePassword( | |||
testEnvironmentCredentialId: 'azure-fxinnovation-application', | |||
publishEnvironmentCredentialId: 'azure-fxinnovation-application', | |||
providerUsernameVariableName: 'client_id', | |||
providerPasswordVariableName: 'client_secret', | |||
initSSHCredentialId: 'gitea-fx_administrator-key', | |||
testPlanVars: [ | |||
"'subscription_id=e469a261-e6fc-4363-94f1-3d8cdb259ec7'", | |||
"'tenant_id=219647b6-1ea6-409d-b9cc-0893cb535884'", | |||
], | |||
publishPlanVars: [ | |||
"'subscription_id=e469a261-e6fc-4363-94f1-3d8cdb259ec7'", | |||
"'tenant_id=219647b6-1ea6-409d-b9cc-0893cb535884'", | |||
], | |||
inspecTarget: 'azure', | |||
inspecSubscriptionId: 'e469a261-e6fc-4363-94f1-3d8cdb259ec7', | |||
inspecTenantId: '219647b6-1ea6-409d-b9cc-0893cb535884' | |||
) | |||
} |
@@ -0,0 +1,21 @@ | |||
MIT License | |||
Copyright (c) 2019-2020 FXinnovation Inc. | |||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||
of this software and associated documentation files (the "Software"), to deal | |||
in the Software without restriction, including without limitation the rights | |||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
copies of the Software, and to permit persons to whom the Software is furnished | |||
to do so, subject to the following conditions: | |||
The above copyright notice and this permission notice (including the next | |||
paragraph) shall be included in all copies or substantial portions of the | |||
Software. | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | |||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF | |||
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
@@ -0,0 +1,50 @@ | |||
# terraform-module-kubernetes-cloudwatch-exporter | |||
Terraform module to deploy [cloudwatch_exporter](https://github.com/prometheus/cloudwatch_exporter) on kubernetes. | |||
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> | |||
## Providers | |||
| Name | Version | | |||
|------|---------| | |||
| kubernetes | n/a | | |||
| random | n/a | | |||
## Inputs | |||
| Name | Description | Type | Default | Required | | |||
|------|-------------|------|---------|:-----:| | |||
| access\_key | Client ID that will be used by the cloudwatch-exporter. | `string` | n/a | yes | | |||
| annotations | Additionnal annotations that will be merged on all resources. | `map` | `{}` | no | | |||
| config\_map\_annotations | Additionnal annotations that will be merged for the config map. | `map` | `{}` | no | | |||
| config\_map\_labels | Additionnal labels that will be merged for the config map. | `map` | `{}` | no | | |||
| config\_map\_name | Name of the config map that will be created. | `string` | `"cloudwatch-exporter"` | no | | |||
| configuration | Object representating the yaml configuration for cloudwatch-exporter. | `any` | n/a | yes | | |||
| deployment\_annotations | Additionnal annotations that will be merged on the deployment. | `map` | `{}` | no | | |||
| deployment\_labels | Additionnal labels that will be merged on the deployment. | `map` | `{}` | no | | |||
| deployment\_name | Name of the deployment that will be create. | `string` | `"cloudwatch-exporter"` | no | | |||
| enabled | Whether or not to enable this module. | `bool` | `true` | no | | |||
| image\_name | Name of the docker image to use. | `string` | `"prom/cloudwatch-exporter"` | no | | |||
| image\_pull\_policy | Image pull policy on the main container. | `string` | `"IfNotPresent"` | no | | |||
| image\_version | Tag of the docker image to use. | `string` | `"latest"` | no | | |||
| labels | Additionnal labels that will be merged on all resources. | `map` | `{}` | no | | |||
| namespace | Namespace in which the module will be deployed. | `string` | `"default"` | no | | |||
| replicas | Number of replicas to deploy. | `number` | `1` | no | | |||
| secret\_annotations | Additionnal annotations that will be merged for the secret. | `map` | `{}` | no | | |||
| secret\_key | Client secret that will be used by the cloudwatch-exporter. | `string` | n/a | yes | | |||
| secret\_labels | Additionnal labels that will be merged for the secret. | `map` | `{}` | no | | |||
| secret\_name | Name of the secret that will be created. | `string` | `"cloudwatch-exporter"` | no | | |||
| service\_annotations | Additionnal annotations that will be merged for the service. | `map` | `{}` | no | | |||
| service\_labels | Additionnal labels that will be merged for the service. | `map` | `{}` | no | | |||
| service\_name | Name of the service that will be create | `string` | `"cloudwatch-exporter"` | no | | |||
## Outputs | |||
| Name | Description | | |||
|------|-------------| | |||
| config\_map\_name | Name of the config\_map created by the module. | | |||
| deployment\_name | Name of the deployment created by the module. | | |||
| secret\_name | Name of the secret created by the module. | | |||
| service\_name | Name of the service created by the module. | | |||
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --> |
@@ -0,0 +1,109 @@ | |||
##### | |||
# Providers | |||
##### | |||
provider "azurerm" { | |||
version = "1.28.0" | |||
client_id = var.client_id | |||
client_secret = var.client_secret | |||
subscription_id = var.subscription_id | |||
tenant_id = var.tenant_id | |||
} | |||
provider "random" { | |||
version = "~> 2" | |||
} | |||
provider "kubernetes" { | |||
version = "1.10.0" | |||
host = data.azurerm_kubernetes_cluster.this.kube_config.0.host | |||
username = data.azurerm_kubernetes_cluster.this.kube_config.0.username | |||
password = data.azurerm_kubernetes_cluster.this.kube_config.0.password | |||
client_certificate = base64decode(data.azurerm_kubernetes_cluster.this.kube_config.0.client_certificate) | |||
client_key = base64decode(data.azurerm_kubernetes_cluster.this.kube_config.0.client_key) | |||
cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.this.kube_config.0.cluster_ca_certificate) | |||
load_config_file = false | |||
} | |||
##### | |||
# Randoms | |||
##### | |||
resource "random_string" "default" { | |||
upper = false | |||
number = false | |||
special = false | |||
length = 8 | |||
} | |||
resource "random_string" "disabled" { | |||
upper = false | |||
number = false | |||
special = false | |||
length = 8 | |||
} | |||
##### | |||
# Datasources | |||
##### | |||
data "azurerm_kubernetes_cluster" "this" { | |||
name = "prometheusplusplus-stg0" | |||
resource_group_name = "prometheusplusplus-stg0" | |||
} | |||
##### | |||
# Context | |||
##### | |||
resource "kubernetes_namespace" "default" { | |||
metadata { | |||
name = random_string.default.result | |||
} | |||
} | |||
resource "kubernetes_namespace" "disabled" { | |||
metadata { | |||
name = random_string.disabled.result | |||
} | |||
} | |||
##### | |||
# default example | |||
##### | |||
module "default" { | |||
source = "../.." | |||
namespace = kubernetes_namespace.default.metadata.0.name | |||
access_key = "fake_key" | |||
secret_key = "fake_secret" | |||
configuration = { | |||
region = "us-east-1" | |||
metrics = [{ | |||
aws_namespace = "AWS/ApplicationELB" | |||
aws_metric_name = "RequestCound" | |||
aws_dimensions = ["LoadBalancer", "TargetGroup"] | |||
aws_tag_select = { | |||
resource_type_selection = "elasticloadbalancing:loadbalancer/app" | |||
resource_id_dimension = "LoadBalancer" | |||
aws_statistics = ["Average"] | |||
} | |||
}] | |||
} | |||
} | |||
##### | |||
# disabled example | |||
##### | |||
module "disabled" { | |||
source = "../.." | |||
enabled = false | |||
namespace = kubernetes_namespace.disabled.metadata.0.name | |||
access_key = "" | |||
secret_key = "" | |||
configuration = {} | |||
} |
@@ -0,0 +1,17 @@ | |||
variable "client_id" { | |||
description = "Client ID that will be used by the snapshot-manager." | |||
type = string | |||
} | |||
variable "client_secret" { | |||
description = "Client secret that will be used by the snapshot-manager." | |||
type = string | |||
} | |||
variable "subscription_id" { | |||
type = string | |||
} | |||
variable "tenant_id" { | |||
type = string | |||
} |
@@ -0,0 +1,274 @@ | |||
##### | |||
# Locals | |||
##### | |||
locals { | |||
labels = { | |||
"app.kubernetes.io/version" = var.image_version | |||
"app.kubernetes.io/component" = "exporter" | |||
"app.kubernetes.io/part-of" = "monitoring" | |||
"app.kubernetes.io/managed-by" = "terraform" | |||
"app.kubernetes.io/name" = "cloudwatch-exporter" | |||
} | |||
configuration = yamlencode(var.configuration) | |||
port = 9106 | |||
} | |||
##### | |||
# Randoms | |||
##### | |||
resource "random_string" "selector" { | |||
special = false | |||
upper = false | |||
number = false | |||
length = 8 | |||
} | |||
##### | |||
# Deployment | |||
##### | |||
resource "kubernetes_deployment" "this" { | |||
count = var.enabled ? 1 : 0 | |||
metadata { | |||
name = var.deployment_name | |||
namespace = var.namespace | |||
annotations = merge( | |||
var.annotations, | |||
var.deployment_annotations | |||
) | |||
labels = merge( | |||
{ | |||
"app.kubernetes.io/instance" = var.deployment_name | |||
}, | |||
local.labels, | |||
var.labels, | |||
var.deployment_labels | |||
) | |||
} | |||
spec { | |||
replicas = 1 | |||
selector { | |||
match_labels = { | |||
app = "cloudwatch-exporter" | |||
random = random_string.selector.result | |||
} | |||
} | |||
template { | |||
metadata { | |||
annotations = merge( | |||
{ | |||
"configuration/hash" = sha256(local.configuration) | |||
}, | |||
var.annotations, | |||
var.deployment_annotations | |||
) | |||
labels = merge( | |||
{ | |||
"app.kubernetes.io/instance" = var.deployment_name | |||
app = "cloudwatch-exporter" | |||
random = random_string.selector.result | |||
}, | |||
local.labels, | |||
var.labels, | |||
var.deployment_labels | |||
) | |||
} | |||
spec { | |||
container { | |||
name = "cloudwatch-exporter" | |||
image = "${var.image_name}:${var.image_version}" | |||
image_pull_policy = var.image_pull_policy | |||
env { | |||
name = "AWS_ACCESS_KEY_ID" | |||
value_from { | |||
secret_key_ref { | |||
name = element(concat(kubernetes_secret.this.*.metadata.0.name, [""]), 0) | |||
key = "access_key" | |||
} | |||
} | |||
} | |||
env { | |||
name = "AWS_SECRET_ACCESS_KEY" | |||
value_from { | |||
secret_key_ref { | |||
name = element(concat(kubernetes_secret.this.*.metadata.0.name, [""]), 0) | |||
key = "secret_key" | |||
} | |||
} | |||
} | |||
readiness_probe { | |||
http_get { | |||
path = "/" | |||
port = local.port | |||
scheme = "HTTP" | |||
} | |||
timeout_seconds = 5 | |||
period_seconds = 5 | |||
success_threshold = 1 | |||
failure_threshold = 35 | |||
initialDelaySeconds = 60 | |||
} | |||
liveness_probe { | |||
http_get { | |||
path = "/" | |||
port = local.port | |||
scheme = "HTTP" | |||
} | |||
timeout_seconds = 5 | |||
period_seconds = 10 | |||
success_threshold = 1 | |||
failure_threshold = 3 | |||
initialDelaySeconds = 90 | |||
} | |||
port { | |||
name = "http" | |||
container_port = local.port | |||
protocol = "TCP" | |||
} | |||
resources { | |||
requests { | |||
memory = "128Mi" | |||
cpu = "50m" | |||
} | |||
limits { | |||
memory = "256Mi" | |||
cpu = "200m" | |||
} | |||
} | |||
volume_mount { | |||
name = "configuration" | |||
mount_path = "/config/config.yml" | |||
sub_path = "config.yml" | |||
} | |||
} | |||
volume { | |||
name = "configuration" | |||
config_map { | |||
name = element(concat(kubernetes_config_map.this.*.metadata.0.name, [""]), 0) | |||
items { | |||
key = "config.yml" | |||
path = "config.yml" | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
##### | |||
# Secret | |||
##### | |||
resource "kubernetes_secret" "this" { | |||
count = var.enabled ? 1 : 0 | |||
metadata { | |||
name = var.secret_name | |||
namespace = var.namespace | |||
annotations = merge( | |||
var.annotations, | |||
var.secret_annotations | |||
) | |||
labels = merge( | |||
{ | |||
"app.kubernetes.io/instance" = var.secret_name | |||
}, | |||
var.labels, | |||
var.secret_labels | |||
) | |||
} | |||
data = { | |||
access_key = var.access_key | |||
secret_key = var.secret_key | |||
} | |||
type = "Opaque" | |||
} | |||
##### | |||
# Service | |||
##### | |||
resource "kubernetes_service" "this" { | |||
count = var.enabled ? 1 : 0 | |||
metadata { | |||
name = var.service_name | |||
namespace = var.namespace | |||
annotations = merge( | |||
{ | |||
"prometheus.io/scrape" = "true" | |||
}, | |||
var.annotations, | |||
var.service_annotations | |||
) | |||
labels = merge( | |||
{ | |||
"app.kubernetes.io/instance" = var.service_name | |||
}, | |||
local.labels, | |||
var.labels, | |||
var.service_labels | |||
) | |||
} | |||
spec { | |||
selector = { | |||
random = random_string.selector.result | |||
app = "cloudwatch-exporter" | |||
} | |||
type = "ClusterIP" | |||
port { | |||
port = 80 | |||
target_port = "http" | |||
protocol = "TCP" | |||
name = "http" | |||
} | |||
} | |||
} | |||
##### | |||
# ConfigMap | |||
##### | |||
resource "kubernetes_config_map" "this" { | |||
count = var.enabled ? 1 : 0 | |||
metadata { | |||
name = var.config_map_name | |||
namespace = var.namespace | |||
annotations = merge( | |||
var.annotations, | |||
var.config_map_annotations | |||
) | |||
labels = merge( | |||
{ | |||
"app.kubernetes.io/instance" = var.config_map_name | |||
}, | |||
local.labels, | |||
var.labels, | |||
var.config_map_labels | |||
) | |||
} | |||
data = { | |||
"config.yml" = local.configuration | |||
} | |||
} |
@@ -0,0 +1,19 @@ | |||
output "deployment_name" { | |||
description = "Name of the deployment created by the module." | |||
value = element(concat(kubernetes_deployment.this.*.metadata.0.name, [""]), 0) | |||
} | |||
output "secret_name" { | |||
description = "Name of the secret created by the module." | |||
value = element(concat(kubernetes_secret.this.*.metadata.0.name, [""]), 0) | |||
} | |||
output "service_name" { | |||
description = "Name of the service created by the module." | |||
value = element(concat(kubernetes_service.this.*.metadata.0.name, [""]), 0) | |||
} | |||
output "config_map_name" { | |||
description = "Name of the config_map created by the module." | |||
value = element(concat(kubernetes_config_map.this.*.metadata.0.name, [""]), 0) | |||
} |
@@ -0,0 +1,138 @@ | |||
##### | |||
# Global | |||
##### | |||
variable "annotations" { | |||
description = "Additionnal annotations that will be merged on all resources." | |||
default = {} | |||
} | |||
variable "enabled" { | |||
description = "Whether or not to enable this module." | |||
default = true | |||
} | |||
variable "labels" { | |||
description = "Additionnal labels that will be merged on all resources." | |||
default = {} | |||
} | |||
variable "namespace" { | |||
description = "Namespace in which the module will be deployed." | |||
default = "default" | |||
} | |||
##### | |||
# Application | |||
##### | |||
variable "access_key" { | |||
description = "Client ID that will be used by the cloudwatch-exporter." | |||
type = string | |||
} | |||
variable "secret_key" { | |||
description = "Client secret that will be used by the cloudwatch-exporter." | |||
type = string | |||
} | |||
variable "configuration" { | |||
description = "Object representating the yaml configuration for cloudwatch-exporter." | |||
type = any | |||
} | |||
##### | |||
# Deployment | |||
##### | |||
variable "deployment_annotations" { | |||
description = "Additionnal annotations that will be merged on the deployment." | |||
default = {} | |||
} | |||
variable "deployment_labels" { | |||
description = "Additionnal labels that will be merged on the deployment." | |||
default = {} | |||
} | |||
variable "deployment_name" { | |||
description = "Name of the deployment that will be create." | |||
default = "cloudwatch-exporter" | |||
} | |||
variable "image_name" { | |||
description = "Name of the docker image to use." | |||
default = "prom/cloudwatch-exporter" | |||
} | |||
variable "image_pull_policy" { | |||
description = "Image pull policy on the main container." | |||
default = "IfNotPresent" | |||
} | |||
variable "image_version" { | |||
description = "Tag of the docker image to use." | |||
default = "latest" | |||
} | |||
variable "replicas" { | |||
description = "Number of replicas to deploy." | |||
default = 1 | |||
} | |||
##### | |||
# Service | |||
##### | |||
variable "service_annotations" { | |||
description = "Additionnal annotations that will be merged for the service." | |||
default = {} | |||
} | |||
variable "service_labels" { | |||
description = "Additionnal labels that will be merged for the service." | |||
default = {} | |||
} | |||
variable "service_name" { | |||
description = "Name of the service that will be create" | |||
default = "cloudwatch-exporter" | |||
} | |||
##### | |||
# Secret | |||
##### | |||
variable "secret_annotations" { | |||
description = "Additionnal annotations that will be merged for the secret." | |||
default = {} | |||
} | |||
variable "secret_labels" { | |||
description = "Additionnal labels that will be merged for the secret." | |||
default = {} | |||
} | |||
variable "secret_name" { | |||
description = "Name of the secret that will be created." | |||
default = "cloudwatch-exporter" | |||
} | |||
##### | |||
# Config Map | |||
##### | |||
variable "config_map_annotations" { | |||
description = "Additionnal annotations that will be merged for the config map." | |||
default = {} | |||
} | |||
variable "config_map_labels" { | |||
description = "Additionnal labels that will be merged for the config map." | |||
default = {} | |||
} | |||
variable "config_map_name" { | |||
description = "Name of the config map that will be created." | |||
default = "cloudwatch-exporter" | |||
} |