feature: simple basic application deployment with service, certificate, dns and ingress exposition available
This commit is contained in:
parent
229ab20e55
commit
b578babd1b
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# Local .terraform directories
|
||||
**/.terraform/*
|
||||
|
||||
# .tfstate files
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
|
||||
# Crash log files
|
||||
crash.log
|
||||
crash.*.log
|
||||
|
||||
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
|
||||
# password, private keys, and other secrets. These should not be part of version
|
||||
# control as they are data points which are potentially sensitive and subject
|
||||
# to change depending on the environment.
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
|
||||
# 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
|
||||
|
||||
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
|
||||
# example: *tfplan*
|
||||
|
||||
# Ignore CLI configuration files
|
||||
.terraformrc
|
||||
terraform.rc
|
||||
|
||||
# intellij
|
||||
*.iml
|
||||
idea/
|
||||
|
138
exposition.tf
Normal file
138
exposition.tf
Normal file
@ -0,0 +1,138 @@
|
||||
locals {
|
||||
service_hostname = format("%s.localdomain", var.application_name)
|
||||
at_least_one_port = length(var.ports) > 0 ? 1 : 0
|
||||
ports_map = {
|
||||
for index, port in var.ports : format("port-%s", index) => port
|
||||
}
|
||||
exposed_ports_map = {
|
||||
for index, port in var.ports :
|
||||
format("port-%s", index) => port if port.expose == true
|
||||
}
|
||||
certificate_secret_name = format("%s-certificate", var.application_name)
|
||||
at_least_one_port_exposed = length(local.exposed_ports_map) > 0 ? 1 : 0
|
||||
}
|
||||
|
||||
resource "kubernetes_service_v1" "service" {
|
||||
count = local.at_least_one_port
|
||||
metadata {
|
||||
name = var.application_name
|
||||
namespace = var.namespace
|
||||
labels = {
|
||||
"app.kubernetes.io/part-of" = var.application_name
|
||||
"app.kubernetes.io/managed-by" = "terraform"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
type = "ClusterIP"
|
||||
|
||||
dynamic port {
|
||||
for_each = local.ports_map
|
||||
content {
|
||||
name = format("service-%s", port.key)
|
||||
port = port.value.container_port
|
||||
target_port = port.key
|
||||
}
|
||||
}
|
||||
selector = {
|
||||
"app.kubernetes.io/name" = local.label_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_manifest" "certificate" {
|
||||
count = local.at_least_one_port_exposed
|
||||
|
||||
manifest = {
|
||||
apiVersion = "cert-manager.io/v1"
|
||||
kind = "Certificate"
|
||||
metadata = {
|
||||
name = var.application_name
|
||||
namespace = var.namespace
|
||||
labels = {
|
||||
"app.kubernetes.io/part-of" = var.application_name
|
||||
"app.kubernetes.io/managed-by" = "terraform"
|
||||
}
|
||||
}
|
||||
spec = {
|
||||
secretName = local.certificate_secret_name
|
||||
dnsNames = [
|
||||
local.service_hostname,
|
||||
format("*.%s", local.service_hostname)
|
||||
]
|
||||
issuerRef = {
|
||||
kind = "ClusterIssuer"
|
||||
name = "localdomain-issuer"
|
||||
group = "cfssl-issuer.wikimedia.org"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_ingress_v1" "ingress" {
|
||||
for_each = local.exposed_ports_map
|
||||
|
||||
metadata {
|
||||
name = var.application_name
|
||||
namespace = var.namespace
|
||||
labels = {
|
||||
"app.kubernetes.io/part-of" = var.application_name
|
||||
"app.kubernetes.io/managed-by" = "terraform"
|
||||
}
|
||||
annotations = {
|
||||
"traefik.ingress.kubernetes.io/router.middlewares" = "kube-ingress-gzip-compress@kubernetescrd"
|
||||
"traefik.ingress.kubernetes.io/router.entrypoints" = "websecure"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
rule {
|
||||
host = local.service_hostname
|
||||
http {
|
||||
path {
|
||||
path = "/"
|
||||
backend {
|
||||
service {
|
||||
name = kubernetes_service_v1.service[0].metadata.0.name
|
||||
port {
|
||||
name = format("service-%s", each.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tls {
|
||||
hosts = [local.service_hostname]
|
||||
secret_name = local.certificate_secret_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# {{ application_name }}.localdomain IN CNAME internal-lb
|
||||
resource "kubernetes_manifest" "record" {
|
||||
count = local.at_least_one_port_exposed
|
||||
|
||||
manifest = {
|
||||
apiVersion = "externaldns.k8s.io/v1alpha1"
|
||||
kind = "DNSEndpoint"
|
||||
metadata = {
|
||||
name = var.application_name
|
||||
namespace = var.namespace
|
||||
labels = {
|
||||
"app.kubernetes.io/part-of" = var.application_name
|
||||
"app.kubernetes.io/managed-by" = "terraform"
|
||||
}
|
||||
}
|
||||
spec = {
|
||||
endpoints = [
|
||||
{
|
||||
dnsName = local.service_hostname
|
||||
recordTTL = "180"
|
||||
recordType = "CNAME"
|
||||
targets = [
|
||||
"internal-lb.localdomain"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
55
input.tf
Normal file
55
input.tf
Normal file
@ -0,0 +1,55 @@
|
||||
variable "application_name" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "namespace" {
|
||||
default = "default"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "image" {
|
||||
type = object({
|
||||
name = string
|
||||
tag = optional(string, "latest")
|
||||
pull-policy = optional(string, "Always")
|
||||
})
|
||||
}
|
||||
|
||||
variable "args" {
|
||||
type = list(string)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "ports" {
|
||||
type = list(
|
||||
object({
|
||||
container_port = number
|
||||
expose = optional(bool, false)
|
||||
})
|
||||
)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "env" {
|
||||
type = list(
|
||||
object({
|
||||
name = string
|
||||
value = string
|
||||
})
|
||||
)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "config_content" {
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "volumes" {
|
||||
type = map(
|
||||
object({
|
||||
path = string
|
||||
})
|
||||
)
|
||||
default = {}
|
||||
}
|
121
main.tf
Normal file
121
main.tf
Normal file
@ -0,0 +1,121 @@
|
||||
resource "random_uuid" "identifier" {
|
||||
}
|
||||
|
||||
locals {
|
||||
label_name = format("%s-%s", var.application_name, random_uuid.identifier.result)
|
||||
}
|
||||
|
||||
resource "kubernetes_persistent_volume_claim_v1" "storage" {
|
||||
for_each = var.volumes
|
||||
metadata {
|
||||
name = format("%s-volumes-%s", var.application_name, each.key)
|
||||
namespace = var.namespace
|
||||
}
|
||||
spec {
|
||||
access_modes = ["ReadWriteMany"]
|
||||
resources {
|
||||
requests = {
|
||||
storage = "2Gi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_config_map_v1" "configuration_file" {
|
||||
count = var.config_content == null ? 0 : 1
|
||||
|
||||
metadata {
|
||||
name = "configuration-files"
|
||||
namespace = var.namespace
|
||||
}
|
||||
data = {
|
||||
"config" = var.config_content
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_deployment_v1" "deployment" {
|
||||
metadata {
|
||||
name = var.application_name
|
||||
namespace = var.namespace
|
||||
labels = {
|
||||
"app.kubernetes.io/part-of" = var.application_name
|
||||
"app.kubernetes.io/managed-by" = "terraform"
|
||||
}
|
||||
}
|
||||
spec {
|
||||
selector {
|
||||
match_labels = {
|
||||
"app.kubernetes.io/name" = local.label_name
|
||||
}
|
||||
}
|
||||
template {
|
||||
metadata {
|
||||
labels = {
|
||||
"app.kubernetes.io/name" = local.label_name
|
||||
}
|
||||
}
|
||||
spec {
|
||||
container {
|
||||
name = var.application_name
|
||||
image = format("%s:%s", var.image.name, var.image.tag)
|
||||
image_pull_policy = var.image.pull-policy
|
||||
args = var.args
|
||||
|
||||
dynamic port {
|
||||
for_each = var.ports
|
||||
content {
|
||||
name = format("port-%s", port.key)
|
||||
container_port = port.value.container_port
|
||||
}
|
||||
}
|
||||
|
||||
dynamic env {
|
||||
for_each = var.env
|
||||
content {
|
||||
name = env.value.name
|
||||
value = env.value.value
|
||||
}
|
||||
}
|
||||
|
||||
dynamic volume_mount {
|
||||
for_each = var.config_content != null ? [
|
||||
kubernetes_config_map_v1.configuration_file.0.metadata.0.name
|
||||
] : []
|
||||
content {
|
||||
name = "config-volume"
|
||||
mount_path = "/application/config.json"
|
||||
sub_path = "config"
|
||||
}
|
||||
}
|
||||
|
||||
dynamic volume_mount {
|
||||
for_each = var.volumes
|
||||
content {
|
||||
name = volume_mount.key
|
||||
mount_path = volume_mount.value.path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamic volume {
|
||||
for_each = var.volumes
|
||||
content {
|
||||
name = volume.key
|
||||
persistent_volume_claim {
|
||||
claim_name = format("%s-volumes-%s", var.application_name, volume.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
dynamic volume {
|
||||
for_each = var.config_content != null ? [kubernetes_config_map_v1.configuration_file.0.metadata.0.name] : []
|
||||
content {
|
||||
name = "config-volume"
|
||||
config_map {
|
||||
name = volume.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user