Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add terraform module #1049

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions terraform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

First install Pomerium Ingress Controller

```terraform
provider "kubernetes" {

}

module "pomerium_ingress_controller" {
source = "git:https://github.com/pomerium/ingress-controller//terraform?ref=v0.28.0"
}
```

Once Pomerium Ingress Controller is installed, you may reference additional configurations via the `Pomerium` CRD.
See https://www.pomerium.com/docs/k8s/configure

```terraform
resource "kubernetes_manifest" "pomerium_config" {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the installation and configuration need be split into separate steps, due to hashicorp/terraform-provider-kubernetes#1367

Copy link

@grandmogbarkin grandmogbarkin Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can also use kubectl_manifest instead of kubernetes_manifest, which doesn't have this issue.

resource "kubectl_manifest" "pomerium_config" {
  yaml_body = <<YAML
apiVersion: ingress.pomerium.io/v1
kind: Pomerium
metadata:
  name: global
spec:
  secrets: pomerium-ingress-controller/bootstrap
YAML
}

manifest = {
apiVersion = "ingress.pomerium.io/v1"
kind = "Pomerium"
metadata = {
name = "global"
}
spec = {
secrets = "pomerium-ingress-controller/bootstrap"
}
}
}
```
37 changes: 37 additions & 0 deletions terraform/cluster_role_bindings.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
resource "kubernetes_cluster_role_binding" "controller" {
metadata {
name = var.controller_cluster_role_name
labels = var.cluster_role_labels
}

role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = kubernetes_cluster_role.controller.metadata[0].name
}

subject {
kind = "ServiceAccount"
name = kubernetes_service_account.controller.metadata[0].name
namespace = kubernetes_namespace.pomerium.metadata[0].name
}
}

resource "kubernetes_cluster_role_binding" "gen_secrets" {
metadata {
name = var.gen_secrets_cluster_role_name
labels = var.cluster_role_labels
}

role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = kubernetes_cluster_role.gen_secrets.metadata[0].name
}

subject {
kind = "ServiceAccount"
name = kubernetes_service_account.gen_secrets.metadata[0].name
namespace = kubernetes_namespace.pomerium.metadata[0].name
}
}
61 changes: 61 additions & 0 deletions terraform/cluster_roles.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
resource "kubernetes_cluster_role" "controller" {
metadata {
name = var.controller_cluster_role_name
labels = var.cluster_role_labels
}

rule {
api_groups = [""]
resources = ["services", "endpoints", "secrets"]
verbs = ["get", "list", "watch"]
}

rule {
api_groups = [""]
resources = ["services/status", "secrets/status", "endpoints/status"]
verbs = ["get"]
}

rule {
api_groups = ["networking.k8s.io"]
resources = ["ingresses", "ingressclasses"]
verbs = ["get", "list", "watch"]
}

rule {
api_groups = ["networking.k8s.io"]
resources = ["ingresses/status"]
verbs = ["get", "patch", "update"]
}

rule {
api_groups = ["ingress.pomerium.io"]
resources = ["pomerium"]
verbs = ["get", "list", "watch"]
}

rule {
api_groups = ["ingress.pomerium.io"]
resources = ["pomerium/status"]
verbs = ["get", "update", "patch"]
}

rule {
api_groups = [""]
resources = ["events"]
verbs = ["create", "patch"]
}
}

resource "kubernetes_cluster_role" "gen_secrets" {
metadata {
name = var.gen_secrets_cluster_role_name
labels = var.cluster_role_labels
}

rule {
api_groups = [""]
resources = ["secrets"]
verbs = ["create"]
}
}
3 changes: 3 additions & 0 deletions terraform/crd.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "kubernetes_manifest" "pomerium_crd" {
manifest = yamldecode(file("${path.module}/crd.yaml"))
}
1 change: 1 addition & 0 deletions terraform/crd.yaml
144 changes: 144 additions & 0 deletions terraform/deployment.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
resource "kubernetes_deployment" "pomerium" {
metadata {
name = var.deployment_name
namespace = var.namespace_name
labels = var.deployment_labels
}

lifecycle {
ignore_changes = [
metadata[0].annotations
]
}

spec {
replicas = var.deployment_replicas

selector {
match_labels = {
"app.kubernetes.io/name" = "pomerium-ingress-controller"
}
}

template {
metadata {
labels = {
"app.kubernetes.io/name" = "pomerium-ingress-controller"
}
}

spec {
service_account_name = kubernetes_service_account.controller.metadata[0].name
termination_grace_period_seconds = 10

security_context {
run_as_non_root = true
}

node_selector = merge(local.default_node_selector, var.node_selector)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional: It's sometimes nicer to do a merge in the local variable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mean :

node_selector = local.node_selector

and then have

locals {
  default_node_selector = {...}
  node_selector = merge(local.default_node_selector, var.node_selector)
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Or local.computed_node_selector to denote it's not a single-sourced value.


container {
name = "pomerium-ingress-controller"
image = "${var.image_repository}:${var.image_tag}"
image_pull_policy = var.image_pull_policy

args = compact([
"all-in-one",
"--pomerium-config=${var.pomerium_config_name}",
"--update-status-from-service=${var.namespace_name}/pomerium-proxy",
"--metrics-bind-address=$(POD_IP):9090",
var.enable_databroker ? "--databroker-auto-tls=pomerium-databroker.${var.namespace_name}.svc" : null,
])

env {
name = "TMPDIR"
value = "/tmp"
}

env {
name = "XDG_CACHE_HOME"
value = "/tmp"
}

env {
name = "POD_IP"
value_from {
field_ref {
field_path = "status.podIP"
}
}
}

port {
container_port = 8443
name = "https"
protocol = "TCP"
}

port {
container_port = 8080
name = "http"
protocol = "TCP"
}

port {
container_port = 9090
name = "metrics"
protocol = "TCP"
}

dynamic "port" {
for_each = var.enable_databroker ? [1] : []
content {
container_port = 5443
name = "databroker"
protocol = "TCP"
}
}

resources {
limits = {
cpu = var.resources_limits_cpu
memory = var.resources_limits_memory
}

requests = {
cpu = var.resources_requests_cpu
memory = var.resources_requests_memory
}
}

security_context {
allow_privilege_escalation = false
read_only_root_filesystem = true
run_as_group = 65532
run_as_non_root = true
run_as_user = 65532
}

volume_mount {
name = "tmp"
mount_path = "/tmp"
}
}

dynamic "toleration" {
for_each = var.tolerations
content {
key = lookup(toleration.value, "key", null)
operator = lookup(toleration.value, "operator", null)
value = lookup(toleration.value, "value", null)
effect = lookup(toleration.value, "effect", null)
toleration_seconds = lookup(toleration.value, "toleration_seconds", null)
}
}

volume {
name = "tmp"

empty_dir {}
}
}
}
}
}
61 changes: 61 additions & 0 deletions terraform/gen_secrets.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
resource "kubernetes_job" "gen_secrets" {
metadata {
name = var.job_name
namespace = var.namespace_name
labels = var.deployment_labels
}

lifecycle {
ignore_changes = [
metadata[0].annotations
]
}

spec {
template {
metadata {
name = var.job_name
labels = var.deployment_labels
}

spec {
service_account_name = kubernetes_service_account.gen_secrets.metadata[0].name
restart_policy = "OnFailure"

security_context {
fs_group = 1000
run_as_non_root = true
run_as_user = 1000
}

node_selector = merge(local.default_node_selector, var.node_selector)

container {
name = "gen-secrets"
image = "${var.image_repository}:${var.image_tag}"
image_pull_policy = "IfNotPresent"

args = [
"gen-secrets",
"--secrets=${var.namespace_name}/bootstrap",
]

security_context {
allow_privilege_escalation = false
}
}

dynamic "toleration" {
for_each = var.tolerations
content {
key = lookup(toleration.value, "key", null)
operator = lookup(toleration.value, "operator", null)
value = lookup(toleration.value, "value", null)
effect = lookup(toleration.value, "effect", null)
toleration_seconds = lookup(toleration.value, "toleration_seconds", null)
}
}
}
}
}
}
10 changes: 10 additions & 0 deletions terraform/ingress_class.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource "kubernetes_ingress_class" "pomerium" {
metadata {
name = var.ingress_class_name
labels = var.labels
}

spec {
controller = "pomerium.io/ingress-controller"
}
}
5 changes: 5 additions & 0 deletions terraform/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
locals {
default_node_selector = {
"kubernetes.io/os" = "linux"
}
}
6 changes: 6 additions & 0 deletions terraform/namespace.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "kubernetes_namespace" "pomerium" {
metadata {
name = var.namespace_name
labels = var.labels
}
}
15 changes: 15 additions & 0 deletions terraform/service_accounts.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
resource "kubernetes_service_account" "controller" {
metadata {
name = var.controller_service_account_name
namespace = kubernetes_namespace.pomerium.metadata[0].name
labels = var.service_account_labels
}
}

resource "kubernetes_service_account" "gen_secrets" {
metadata {
name = var.gen_secrets_service_account_name
namespace = kubernetes_namespace.pomerium.metadata[0].name
labels = var.service_account_labels
}
}
Loading
Loading