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