Browse Source

feat: initial version of the module

tags/0.1.0
commit
8bc074dfde
Signed by: christophe.vkerchove <christophe.vkerchove@fxinnovation.com> GPG Key ID: FC22F2DA87F093F1
12 changed files with 703 additions and 0 deletions
  1. +27
    -0
      .gitignore
  2. +14
    -0
      .pre-commit-config.yaml
  3. +1
    -0
      AUTHORS
  4. +5
    -0
      CHANGELOG.md
  5. +28
    -0
      Jenkinsfile
  6. +21
    -0
      LICENSE
  7. +50
    -0
      README.md
  8. +109
    -0
      examples/default/deploy.tf
  9. +17
    -0
      examples/default/variables.tf
  10. +274
    -0
      main.tf
  11. +19
    -0
      outputs.tf
  12. +138
    -0
      variables.tf

+ 27
- 0
.gitignore View File

@@ -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

+ 14
- 0
.pre-commit-config.yaml View File

@@ -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

+ 1
- 0
AUTHORS View File

@@ -0,0 +1 @@
Christophe van de Kerchove <christophe.vkerchove@fxinnovation.com>

+ 5
- 0
CHANGELOG.md View File

@@ -0,0 +1,5 @@

0.1.0 / 2020-02-07
==================

* feat: initial version of the module

+ 28
- 0
Jenkinsfile View File

@@ -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'
)
}

+ 21
- 0
LICENSE View File

@@ -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.

+ 50
- 0
README.md View File

@@ -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 -->

+ 109
- 0
examples/default/deploy.tf View File

@@ -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 = {}
}

+ 17
- 0
examples/default/variables.tf View File

@@ -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
}

+ 274
- 0
main.tf View File

@@ -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
}
}

+ 19
- 0
outputs.tf View File

@@ -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)
}

+ 138
- 0
variables.tf View File

@@ -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"
}

Loading…
Cancel
Save