From d392b0f561a6df2ae43e42bd3e9ebbe371093057 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Fri, 25 Oct 2024 15:19:56 -0400 Subject: [PATCH 1/8] ingress-controller: terraform --- .../kustomize/crd/bases/README.md | 0 .../ingress.pomerium.io_pomerium.yaml.yaml | 410 ++++++++++++++++++ ingress-controller/terraform/README.md | 33 ++ .../terraform/cluster_role_bindings.tf | 37 ++ ingress-controller/terraform/cluster_roles.tf | 61 +++ ingress-controller/terraform/crd.tf | 3 + ingress-controller/terraform/crd.yaml | 1 + ingress-controller/terraform/deployment.tf | 144 ++++++ ingress-controller/terraform/gen_secrets.tf | 61 +++ ingress-controller/terraform/ingress_class.tf | 10 + ingress-controller/terraform/locals.tf | 5 + ingress-controller/terraform/namespace.tf | 7 + .../terraform/service_accounts.tf | 15 + ingress-controller/terraform/services.tf | 75 ++++ ingress-controller/terraform/variables.tf | 201 +++++++++ 15 files changed, 1063 insertions(+) create mode 100644 ingress-controller/kustomize/crd/bases/README.md create mode 100644 ingress-controller/kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml.yaml create mode 100644 ingress-controller/terraform/README.md create mode 100644 ingress-controller/terraform/cluster_role_bindings.tf create mode 100644 ingress-controller/terraform/cluster_roles.tf create mode 100644 ingress-controller/terraform/crd.tf create mode 120000 ingress-controller/terraform/crd.yaml create mode 100644 ingress-controller/terraform/deployment.tf create mode 100644 ingress-controller/terraform/gen_secrets.tf create mode 100644 ingress-controller/terraform/ingress_class.tf create mode 100644 ingress-controller/terraform/locals.tf create mode 100644 ingress-controller/terraform/namespace.tf create mode 100644 ingress-controller/terraform/service_accounts.tf create mode 100644 ingress-controller/terraform/services.tf create mode 100644 ingress-controller/terraform/variables.tf diff --git a/ingress-controller/kustomize/crd/bases/README.md b/ingress-controller/kustomize/crd/bases/README.md new file mode 100644 index 0000000..e69de29 diff --git a/ingress-controller/kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml.yaml b/ingress-controller/kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml.yaml new file mode 100644 index 0000000..29ba056 --- /dev/null +++ b/ingress-controller/kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml.yaml @@ -0,0 +1,410 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: pomerium.ingress.pomerium.io +spec: + group: ingress.pomerium.io + names: + kind: Pomerium + listKind: PomeriumList + plural: pomerium + singular: pomerium + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + Pomerium define runtime-configurable Pomerium settings + that do not fall into the category of deployment parameters + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PomeriumSpec defines Pomerium-specific configuration parameters. + properties: + accessLogFields: + description: AccessLogFields sets the access + fields to log. + items: + type: string + type: array + authenticate: + description: |- + Authenticate sets authenticate service parameters. + If not specified, a Pomerium-hosted authenticate service would be used. + properties: + callbackPath: + description: |- + CallbackPath sets the path at which the authenticate service receives callback responses + from your identity provider. The value must exactly match one of the authorized redirect URIs for the OAuth 2.0 client. + + +

This value is referred to as the redirect_url in the OpenIDConnect and OAuth2 specs.

+

Defaults to /oauth2/callback

+ type: string + url: + description: "AuthenticateURL is a dedicated domain URL\nthe non-authenticated + persons would be referred to.\n\n\n

" + format: uri + pattern: ^https:// + type: string + required: + - url + type: object + authorizeLogFields: + description: AuthorizeLogFields sets the authorize + fields to log. + items: + type: string + type: array + caSecrets: + description: CASecret should refer to k8s secrets with key ca.crt + containing a CA certificate. + items: + type: string + type: array + certificates: + description: Certificates is a list of secrets of type TLS to use + format: namespace/name + items: + type: string + type: array + cookie: + description: Cookie defines Pomerium session cookie options. + properties: + domain: + description: |- + Domain defaults to the same host that set the cookie. + If you specify the domain explicitly, then subdomains would also be included. + type: string + expire: + description: |- + Expire sets cookie and Pomerium session expiration time. + Once session expires, users would have to re-login. + If you change this parameter, existing sessions are not affected. +

See Session Management + (Enterprise) for a more fine-grained session controls.

+

Defaults to 14 hours.

+ format: duration + type: string + httpOnly: + description: |- + HTTPOnly if set to false, the cookie would be accessible from within the JavaScript. + Defaults to true. + type: boolean + name: + description: |- + Name sets the Pomerium session cookie name. + Defaults to _pomerium + type: string + sameSite: + description: |- + SameSite sets the SameSite option for cookies. + Defaults to . + enum: + - strict + - lax + - none + type: string + type: object + identityProvider: + description: |- + IdentityProvider configure single-sign-on authentication and user identity details + by integrating with your Identity Provider + properties: + provider: + description: |- + Provider is the short-hand name of a built-in OpenID Connect (oidc) identity provider to be used for authentication. + To use a generic provider, set to oidc. + enum: + - auth0 + - azure + - github + - gitlab + - google + - oidc + - okta + - onelogin + - ping + type: string + refreshDirectory: + description: |- + RefreshDirectory is no longer supported, + please see Upgrade Guide. + properties: + interval: + description: interval is the time that pomerium will sync + your IDP directory. + format: duration + type: string + timeout: + description: timeout is the maximum time allowed each run. + format: duration + type: string + required: + - interval + - timeout + type: object + requestParams: + additionalProperties: + type: string + description: RequestParams to be added as part of a sign-in request + using OAuth2 code flow. + format: namespace/name + type: object + requestParamsSecret: + description: RequestParamsSecret is a reference to a secret for + additional parameters you'd prefer not to provide in plaintext. + format: namespace/name + type: string + scopes: + description: |- + Scopes Identity provider scopes correspond to access privilege scopes + as defined in Section 3.3 of OAuth 2.0 RFC6749. + items: + type: string + type: array + secret: + description: |- + Secret containing IdP provider specific parameters. + and must contain at least client_id and client_secret values. + format: namespace/name + minLength: 1 + type: string + serviceAccountFromSecret: + description: |- + ServiceAccountFromSecret is no longer supported, + see Upgrade Guide. + type: string + url: + description: |- + URL is the base path to an identity provider's OpenID connect discovery document. + See Identity Providers guides for details. + format: uri + pattern: ^https:// + type: string + required: + - provider + - secret + type: object + jwtClaimHeaders: + additionalProperties: + type: string + description: |- + JWTClaimHeaders convert claims from the assertion token + into HTTP headers and adds them into JWT assertion header. + Please make sure to read + + Getting User Identity guide. + type: object + passIdentityHeaders: + description: PassIdentityHeaders sets the pass + identity headers option. + type: boolean + programmaticRedirectDomains: + description: |- + ProgrammaticRedirectDomains specifies a list of domains that can be used for + programmatic redirects. + items: + type: string + type: array + runtimeFlags: + additionalProperties: + type: boolean + description: RuntimeFlags sets the runtime + flags to enable/disable certain features. + type: object + secrets: + description: "Secrets references a Secret with Pomerium bootstrap + parameters.\n\n\n

\n

\n

\n

\nIn + a default Pomerium installation manifest, they would be generated + via a\none-time + job\nand stored in a pomerium/bootstrap Secret.\nYou + may re-run the job to rotate the secrets, or update the Secret values + manually.\n

" + format: namespace/name + minLength: 1 + type: string + setResponseHeaders: + additionalProperties: + type: string + description: |- + SetResponseHeaders specifies a mapping of HTTP Header to be added globally to all managed routes and pomerium's authenticate service. + See Set Response Headers + type: object + storage: + description: |- + Storage defines persistent storage for sessions and other data. + See Storage for details. + If no storage is specified, Pomerium would use a transient in-memory storage (not recommended for production). + properties: + postgres: + description: Postgres specifies PostgreSQL database connection + parameters + properties: + caSecret: + description: |- + CASecret should refer to a k8s secret with key ca.crt containing CA certificate + that, if specified, would be used to populate sslrootcert parameter of the connection string. + format: namespace/name + minLength: 1 + type: string + secret: + description: |- + Secret specifies a name of a Secret that must contain + connection key. See + DSN Format and Parameters. + Do not set sslrootcert, sslcert and sslkey via connection string, + use tlsSecret and caSecret CRD options instead. + format: namespace/name + minLength: 1 + type: string + tlsSecret: + description: |- + TLSSecret should refer to a k8s secret of type kubernetes.io/tls + and allows to specify an optional client certificate and key, + by constructing sslcert and sslkey connection string + + parameter values. + format: namespace/name + minLength: 1 + type: string + required: + - secret + type: object + type: object + timeouts: + description: Timeout specifies the global + timeouts for all routes. + properties: + idle: + description: Idle specifies the time at which a downstream or + upstream connection will be terminated if there are no active + streams. + format: duration + type: string + read: + description: Read specifies the amount of time for the entire + request stream to be received from the client. + format: duration + type: string + write: + description: |- + Write specifies max stream duration is the maximum time that a stream’s lifetime will span. + An HTTP request/response exchange fully consumes a single stream. + Therefore, this value must be greater than read_timeout as it covers both request and response time. + format: duration + type: string + type: object + useProxyProtocol: + description: UseProxyProtocol enables Proxy + Protocol support. + type: boolean + required: + - secrets + type: object + status: + description: PomeriumStatus represents configuration and Ingress status. + properties: + ingress: + additionalProperties: + description: |- + ResourceStatus represents the outcome of the latest attempt to reconcile + relevant Kubernetes resource with Pomerium. + properties: + error: + description: Error that prevented latest observedGeneration + to be synchronized with Pomerium. + type: string + observedAt: + description: ObservedAt is when last reconciliation attempt + was made. + format: date-time + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that was last presented to Pomerium. + format: int64 + type: integer + reconciled: + description: Reconciled is whether this object generation was + successfully synced with pomerium. + type: boolean + warnings: + description: Warnings while parsing the resource. + items: + type: string + type: array + required: + - reconciled + type: object + description: Routes provide per-Ingress status. + type: object + settingsStatus: + description: SettingsStatus represent most recent main configuration + reconciliation status. + properties: + error: + description: Error that prevented latest observedGeneration to + be synchronized with Pomerium. + type: string + observedAt: + description: ObservedAt is when last reconciliation attempt was + made. + format: date-time + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that was last presented to Pomerium. + format: int64 + type: integer + reconciled: + description: Reconciled is whether this object generation was + successfully synced with pomerium. + type: boolean + warnings: + description: Warnings while parsing the resource. + items: + type: string + type: array + required: + - reconciled + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/ingress-controller/terraform/README.md b/ingress-controller/terraform/README.md new file mode 100644 index 0000000..7e030f1 --- /dev/null +++ b/ingress-controller/terraform/README.md @@ -0,0 +1,33 @@ +This Terraform module installs + +```terraform +provider "kubernetes" { + +} + +module "pomerium_ingress_controller" { + source = "git:https://github.com/pomerium/install//ingress-controller/terraform?ref=REF" +} +``` + +Where `REF` may be an individual commit, a branch (i.e. `main`) or version tag (i.e. `v0.27.2`). + +Once Pomerium Ingress Controller is installed, you may reference additional configurations via the `Pomerium` CRD. +See https://www.pomerium.com/docs/k8s/configure + +As it has to reference a CRD that does not exist until installed, the configuration manifest has to be created part of a separate Terraform run. + +```terraform +resource "kubernetes_manifest" "pomerium_config" { + manifest = { + apiVersion = "ingress.pomerium.io/v1" + kind = "Pomerium" + metadata = { + name = "global" + } + spec = { + secrets = "pomerium-ingress-controller/bootstrap" + } + } +} +``` diff --git a/ingress-controller/terraform/cluster_role_bindings.tf b/ingress-controller/terraform/cluster_role_bindings.tf new file mode 100644 index 0000000..2f61193 --- /dev/null +++ b/ingress-controller/terraform/cluster_role_bindings.tf @@ -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 + } +} diff --git a/ingress-controller/terraform/cluster_roles.tf b/ingress-controller/terraform/cluster_roles.tf new file mode 100644 index 0000000..e2b6b2c --- /dev/null +++ b/ingress-controller/terraform/cluster_roles.tf @@ -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"] + } +} diff --git a/ingress-controller/terraform/crd.tf b/ingress-controller/terraform/crd.tf new file mode 100644 index 0000000..11ffcca --- /dev/null +++ b/ingress-controller/terraform/crd.tf @@ -0,0 +1,3 @@ +resource "kubernetes_manifest" "pomerium_crd" { + manifest = yamldecode(file("${path.module}/crd.yaml")) +} diff --git a/ingress-controller/terraform/crd.yaml b/ingress-controller/terraform/crd.yaml new file mode 120000 index 0000000..72566dc --- /dev/null +++ b/ingress-controller/terraform/crd.yaml @@ -0,0 +1 @@ +../kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml.yaml \ No newline at end of file diff --git a/ingress-controller/terraform/deployment.tf b/ingress-controller/terraform/deployment.tf new file mode 100644 index 0000000..6fbdbbf --- /dev/null +++ b/ingress-controller/terraform/deployment.tf @@ -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) + + 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 {} + } + } + } + } +} diff --git a/ingress-controller/terraform/gen_secrets.tf b/ingress-controller/terraform/gen_secrets.tf new file mode 100644 index 0000000..a9f074d --- /dev/null +++ b/ingress-controller/terraform/gen_secrets.tf @@ -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) + } + } + } + } + } +} diff --git a/ingress-controller/terraform/ingress_class.tf b/ingress-controller/terraform/ingress_class.tf new file mode 100644 index 0000000..1b6eeb8 --- /dev/null +++ b/ingress-controller/terraform/ingress_class.tf @@ -0,0 +1,10 @@ +resource "kubernetes_ingress_class" "pomerium" { + metadata { + name = var.ingress_class_name + labels = var.labels + } + + spec { + controller = "pomerium.io/ingress-controller" + } +} diff --git a/ingress-controller/terraform/locals.tf b/ingress-controller/terraform/locals.tf new file mode 100644 index 0000000..46cfeab --- /dev/null +++ b/ingress-controller/terraform/locals.tf @@ -0,0 +1,5 @@ +locals { + default_node_selector = { + "kubernetes.io/os" = "linux" + } +} diff --git a/ingress-controller/terraform/namespace.tf b/ingress-controller/terraform/namespace.tf new file mode 100644 index 0000000..f9e674e --- /dev/null +++ b/ingress-controller/terraform/namespace.tf @@ -0,0 +1,7 @@ +resource "kubernetes_namespace" "pomerium" { + count = var.use_external_namespace ? 0 : 1 + metadata { + name = var.namespace_name + labels = var.labels + } +} diff --git a/ingress-controller/terraform/service_accounts.tf b/ingress-controller/terraform/service_accounts.tf new file mode 100644 index 0000000..7d541b9 --- /dev/null +++ b/ingress-controller/terraform/service_accounts.tf @@ -0,0 +1,15 @@ +resource "kubernetes_service_account" "controller" { + metadata { + name = var.controller_service_account_name + namespace = locals.namespace_name + labels = var.service_account_labels + } +} + +resource "kubernetes_service_account" "gen_secrets" { + metadata { + name = var.gen_secrets_service_account_name + namespace = locals.namespace_name + labels = var.service_account_labels + } +} diff --git a/ingress-controller/terraform/services.tf b/ingress-controller/terraform/services.tf new file mode 100644 index 0000000..1285421 --- /dev/null +++ b/ingress-controller/terraform/services.tf @@ -0,0 +1,75 @@ +resource "kubernetes_service" "proxy" { + count = var.proxy_service_type == null ? 0 : 1 + + metadata { + name = "pomerium-proxy" + namespace = var.namespace_name + labels = var.service_labels + } + + lifecycle { + ignore_changes = [ + metadata[0].annotations + ] + } + + spec { + selector = { + "app.kubernetes.io/name" = "pomerium-ingress-controller" + } + + external_traffic_policy = var.proxy_service_type == "LoadBalancer" ? "Local" : null + + port { + name = "https" + port = var.proxy_port_https + node_port = var.proxy_node_port_https + target_port = "https" + protocol = "TCP" + } + + dynamic "port" { + for_each = var.proxy_port_http != null ? [var.proxy_port_http] : [] + content { + name = "http" + port = port.value + node_port = var.proxy_node_port_http + target_port = "http" + protocol = "TCP" + } + } + + type = var.proxy_service_type + } +} + +resource "kubernetes_service" "databroker" { + count = var.enable_databroker ? 1 : 0 + + metadata { + name = "pomerium-databroker" + namespace = kubernetes_namespace.pomerium.metadata[0].name + labels = var.service_labels + } + + lifecycle { + ignore_changes = [ + metadata[0].annotations + ] + } + + spec { + selector = { + "app.kubernetes.io/name" = "pomerium-ingress-controller" + } + + port { + name = "databroker" + port = 443 + target_port = "databroker" + protocol = "TCP" + } + + type = "ClusterIP" + } +} diff --git a/ingress-controller/terraform/variables.tf b/ingress-controller/terraform/variables.tf new file mode 100644 index 0000000..dea84e8 --- /dev/null +++ b/ingress-controller/terraform/variables.tf @@ -0,0 +1,201 @@ +variable "namespace_name" { + description = "The name of the namespace to create" + type = string + default = "pomerium-ingress-controller" +} + +variable "use_external_namespace" { + description = "Skip creating the namespace, assume it already exists, and use the provided namespace name" + type = bool + default = false +} + +variable "labels" { + description = "Labels to apply to resources" + type = map(string) + default = { + "app.kubernetes.io/name" = "pomerium-ingress-controller" + } +} + +variable "image_repository" { + description = "Container image repository" + type = string + default = "pomerium/ingress-controller" +} + +variable "image_tag" { + description = "Container image tag" + type = string + default = "v0.27.0" +} + +variable "image_pull_policy" { + description = "Image pull policy" + type = string + default = "IfNotPresent" +} + +variable "controller_service_account_name" { + description = "Name of the controller service account" + type = string + default = "pomerium-ingress-controller" +} + +variable "gen_secrets_service_account_name" { + description = "Name of the gen-secrets service account" + type = string + default = "pomerium-ingress-controller-gen-secrets" +} + +variable "controller_cluster_role_name" { + description = "Name of the controller cluster role" + type = string + default = "pomerium-ingress-controller" +} + +variable "gen_secrets_cluster_role_name" { + description = "Name of the gen-secrets cluster role" + type = string + default = "pomerium-ingress-controller-gen-secrets" +} + +variable "deployment_name" { + description = "Name of the Deployment" + type = string + default = "pomerium-ingress-controller" +} + +variable "deployment_replicas" { + description = "Number of replicas for the Deployment" + type = number + default = 1 +} + +variable "resources_requests_cpu" { + description = "CPU requests for the Deployment" + type = string + default = "300m" +} + +variable "resources_requests_memory" { + description = "Memory requests for the Deployment" + type = string + default = "200Mi" +} + +variable "resources_limits_cpu" { + description = "CPU limits for the Deployment" + type = string + default = "5000m" +} + +variable "resources_limits_memory" { + description = "Memory limits for the Deployment" + type = string + default = "1Gi" +} + +variable "proxy_service_type" { + description = "Type of the Proxy Service" + type = string + default = "LoadBalancer" +} + +variable "ingress_class_name" { + description = "Name of the IngressClass" + type = string + default = "pomerium" +} + +variable "service_account_labels" { + description = "Labels to apply to service accounts" + type = map(string) + default = { + "app.kubernetes.io/name" = "pomerium-ingress-controller" + } +} + +variable "cluster_role_labels" { + description = "Labels to apply to cluster roles" + type = map(string) + default = { + "app.kubernetes.io/name" = "pomerium-ingress-controller" + } +} + +variable "service_labels" { + description = "Labels to apply to services" + type = map(string) + default = { + "app.kubernetes.io/name" = "pomerium-ingress-controller" + } +} + +variable "deployment_labels" { + description = "Labels to apply to the deployment" + type = map(string) + default = { + "app.kubernetes.io/name" = "pomerium-ingress-controller" + } +} + +variable "tolerations" { + description = "List of tolerations for the pods." + type = list(object({ + key = optional(string) + operator = optional(string, "Equal") + value = optional(string) + effect = optional(string) + toleration_seconds = optional(number) + })) + default = [] +} + +variable "job_name" { + description = "Name of the Job" + type = string + default = "pomerium-gen-secrets" +} + +variable "pomerium_config_name" { + description = "Name of the Pomerium CRD" + type = string + default = "global" +} + +variable "enable_databroker" { + description = "Enable the databroker" + type = bool + default = false +} + +variable "proxy_port_https" { + description = "Port for HTTPS" + type = number + default = 443 +} + +variable "proxy_port_http" { + description = "Port for HTTP" + type = number + default = 80 +} + +variable "proxy_node_port_https" { + description = "Node port for HTTPS, only used when proxy_service_type is NodePort" + type = number + default = null +} + +variable "proxy_node_port_http" { + description = "Host port for HTTP" + type = number + default = null +} + +variable "node_selector" { + description = "Node selector for the Deployment" + type = map(string) + default = {} +} From a82b60fb1dd8c350bea7444e1a2d87a3e727eaa2 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Wed, 30 Oct 2024 18:07:05 -0400 Subject: [PATCH 2/8] remove gen-secrets job, use providers for secret generation --- .../terraform/cluster_role_bindings.tf | 20 +----- ingress-controller/terraform/cluster_roles.tf | 13 ---- ingress-controller/terraform/deployment.tf | 4 ++ ingress-controller/terraform/gen_secrets.tf | 61 ------------------- ingress-controller/terraform/locals.tf | 2 + ingress-controller/terraform/providers.tf | 18 ++++++ ingress-controller/terraform/secrets.tf | 31 ++++++++++ .../terraform/service_accounts.tf | 4 +- ingress-controller/terraform/services.tf | 2 +- 9 files changed, 59 insertions(+), 96 deletions(-) delete mode 100644 ingress-controller/terraform/gen_secrets.tf create mode 100644 ingress-controller/terraform/providers.tf create mode 100644 ingress-controller/terraform/secrets.tf diff --git a/ingress-controller/terraform/cluster_role_bindings.tf b/ingress-controller/terraform/cluster_role_bindings.tf index 2f61193..bc3dc0b 100644 --- a/ingress-controller/terraform/cluster_role_bindings.tf +++ b/ingress-controller/terraform/cluster_role_bindings.tf @@ -13,25 +13,7 @@ resource "kubernetes_cluster_role_binding" "controller" { subject { kind = "ServiceAccount" name = kubernetes_service_account.controller.metadata[0].name - namespace = kubernetes_namespace.pomerium.metadata[0].name + namespace = var.namespace_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 - } -} diff --git a/ingress-controller/terraform/cluster_roles.tf b/ingress-controller/terraform/cluster_roles.tf index e2b6b2c..88eb68d 100644 --- a/ingress-controller/terraform/cluster_roles.tf +++ b/ingress-controller/terraform/cluster_roles.tf @@ -46,16 +46,3 @@ resource "kubernetes_cluster_role" "controller" { 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"] - } -} diff --git a/ingress-controller/terraform/deployment.tf b/ingress-controller/terraform/deployment.tf index 6fbdbbf..eda673d 100644 --- a/ingress-controller/terraform/deployment.tf +++ b/ingress-controller/terraform/deployment.tf @@ -5,6 +5,10 @@ resource "kubernetes_deployment" "pomerium" { labels = var.deployment_labels } + depends_on = [ + kubernetes_secret.bootstrap + ] + lifecycle { ignore_changes = [ metadata[0].annotations diff --git a/ingress-controller/terraform/gen_secrets.tf b/ingress-controller/terraform/gen_secrets.tf deleted file mode 100644 index a9f074d..0000000 --- a/ingress-controller/terraform/gen_secrets.tf +++ /dev/null @@ -1,61 +0,0 @@ -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) - } - } - } - } - } -} diff --git a/ingress-controller/terraform/locals.tf b/ingress-controller/terraform/locals.tf index 46cfeab..7544653 100644 --- a/ingress-controller/terraform/locals.tf +++ b/ingress-controller/terraform/locals.tf @@ -2,4 +2,6 @@ locals { default_node_selector = { "kubernetes.io/os" = "linux" } + + secrets_name = "bootstrap" } diff --git a/ingress-controller/terraform/providers.tf b/ingress-controller/terraform/providers.tf new file mode 100644 index 0000000..adb432f --- /dev/null +++ b/ingress-controller/terraform/providers.tf @@ -0,0 +1,18 @@ +terraform { + required_providers { + tls = { + source = "hashicorp/tls" + version = "~> 4.0" + } + + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2.0" + } + + random = { + source = "hashicorp/random" + version = "~> 3.0" + } + } +} diff --git a/ingress-controller/terraform/secrets.tf b/ingress-controller/terraform/secrets.tf new file mode 100644 index 0000000..f0328ff --- /dev/null +++ b/ingress-controller/terraform/secrets.tf @@ -0,0 +1,31 @@ +resource "kubernetes_secret" "bootstrap" { + metadata { + name = local.secrets_name + namespace = var.namespace_name + } + + type = "Opaque" + + binary_data = { + "shared_secret" = random_bytes.shared_secret.base64 + "cookie_secret" = random_bytes.cookie_secret.base64 + } + + data = { + "signing_key" = tls_private_key.signing_key.private_key_pem + } +} + +resource "tls_private_key" "signing_key" { + algorithm = "ECDSA" + ecdsa_curve = "P256" +} + +resource "random_bytes" "shared_secret" { + length = 32 +} + +resource "random_bytes" "cookie_secret" { + length = 32 +} + diff --git a/ingress-controller/terraform/service_accounts.tf b/ingress-controller/terraform/service_accounts.tf index 7d541b9..4336712 100644 --- a/ingress-controller/terraform/service_accounts.tf +++ b/ingress-controller/terraform/service_accounts.tf @@ -1,7 +1,7 @@ resource "kubernetes_service_account" "controller" { metadata { name = var.controller_service_account_name - namespace = locals.namespace_name + namespace = var.namespace_name labels = var.service_account_labels } } @@ -9,7 +9,7 @@ resource "kubernetes_service_account" "controller" { resource "kubernetes_service_account" "gen_secrets" { metadata { name = var.gen_secrets_service_account_name - namespace = locals.namespace_name + namespace = var.namespace_name labels = var.service_account_labels } } diff --git a/ingress-controller/terraform/services.tf b/ingress-controller/terraform/services.tf index 1285421..c35d13e 100644 --- a/ingress-controller/terraform/services.tf +++ b/ingress-controller/terraform/services.tf @@ -48,7 +48,7 @@ resource "kubernetes_service" "databroker" { metadata { name = "pomerium-databroker" - namespace = kubernetes_namespace.pomerium.metadata[0].name + namespace = var.namespace_name labels = var.service_labels } From ee3557beb1b1c702182df256a9074fff2b299253 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Wed, 30 Oct 2024 18:12:43 -0400 Subject: [PATCH 3/8] rm unusused gen-secrets service account --- ingress-controller/terraform/service_accounts.tf | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ingress-controller/terraform/service_accounts.tf b/ingress-controller/terraform/service_accounts.tf index 4336712..070e9bf 100644 --- a/ingress-controller/terraform/service_accounts.tf +++ b/ingress-controller/terraform/service_accounts.tf @@ -6,10 +6,3 @@ resource "kubernetes_service_account" "controller" { } } -resource "kubernetes_service_account" "gen_secrets" { - metadata { - name = var.gen_secrets_service_account_name - namespace = var.namespace_name - labels = var.service_account_labels - } -} From 942a166caa00eef85c470ca3b255335b38f40136 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Wed, 30 Oct 2024 18:30:36 -0400 Subject: [PATCH 4/8] fix labels --- ingress-controller/terraform/deployment.tf | 10 +++------- ingress-controller/terraform/locals.tf | 14 ++++++++++++++ ingress-controller/terraform/variables.tf | 8 +++++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ingress-controller/terraform/deployment.tf b/ingress-controller/terraform/deployment.tf index eda673d..869320b 100644 --- a/ingress-controller/terraform/deployment.tf +++ b/ingress-controller/terraform/deployment.tf @@ -2,7 +2,7 @@ resource "kubernetes_deployment" "pomerium" { metadata { name = var.deployment_name namespace = var.namespace_name - labels = var.deployment_labels + labels = local.deployment_labels } depends_on = [ @@ -19,16 +19,12 @@ resource "kubernetes_deployment" "pomerium" { replicas = var.deployment_replicas selector { - match_labels = { - "app.kubernetes.io/name" = "pomerium-ingress-controller" - } + match_labels = local.pod_labels } template { metadata { - labels = { - "app.kubernetes.io/name" = "pomerium-ingress-controller" - } + labels = local.pod_labels } spec { diff --git a/ingress-controller/terraform/locals.tf b/ingress-controller/terraform/locals.tf index 7544653..c88f20a 100644 --- a/ingress-controller/terraform/locals.tf +++ b/ingress-controller/terraform/locals.tf @@ -4,4 +4,18 @@ locals { } secrets_name = "bootstrap" + + default_labels = { + "app.kubernetes.io/name" = "pomerium-ingress-controller" + "app.kubernetes.io/version" = var.image_tag + "app.kubernetes.io/managed-by" = "terraform" + } + + default_pod_labels = { + "app.kubernetes.io/component" = "proxy" + } + + deployment_labels = merge(local.default_labels, var.labels) + pod_labels = merge(local.deployment_labels, local.default_pod_labels, var.pod_labels) } + diff --git a/ingress-controller/terraform/variables.tf b/ingress-controller/terraform/variables.tf index dea84e8..add5549 100644 --- a/ingress-controller/terraform/variables.tf +++ b/ingress-controller/terraform/variables.tf @@ -18,6 +18,12 @@ variable "labels" { } } +variable "pod_labels" { + description = "Labels to apply to pods" + type = map(string) + default = {} +} + variable "image_repository" { description = "Container image repository" type = string @@ -27,7 +33,7 @@ variable "image_repository" { variable "image_tag" { description = "Container image tag" type = string - default = "v0.27.0" + default = "v0.27.2" } variable "image_pull_policy" { From 8e2da7931e7fbc859fd6245922f9ca22b7cc8ad8 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Wed, 30 Oct 2024 22:24:24 -0400 Subject: [PATCH 5/8] allow defining config right away --- ingress-controller/terraform/config.tf | 46 ++++++++++++++++++++++ ingress-controller/terraform/crd.tf | 5 ++- ingress-controller/terraform/deployment.tf | 2 +- ingress-controller/terraform/locals.tf | 2 + ingress-controller/terraform/providers.tf | 6 +++ ingress-controller/terraform/variables.tf | 19 +++++++++ 6 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 ingress-controller/terraform/config.tf diff --git a/ingress-controller/terraform/config.tf b/ingress-controller/terraform/config.tf new file mode 100644 index 0000000..04dd116 --- /dev/null +++ b/ingress-controller/terraform/config.tf @@ -0,0 +1,46 @@ +resource "kubectl_manifest" "pomerium_config" { + count = local.create_config ? 1 : 0 + + depends_on = [kubectl_manifest.pomerium_crd] + yaml_body = yamlencode({ + apiVersion = "ingress.pomerium.io/v1" + kind = "Pomerium" + metadata = { + name = "${var.pomerium_config_name}" + } + spec = { + secrets = "${var.namespace_name}/${local.secrets_name}" + identityProvider = local.idp_config != null ? { + provider = local.idp_config.provider + secret = "${var.namespace_name}/${local.idp_secret_name}" + url = local.idp_config.url + } : null + } + }) +} + +resource "kubernetes_secret" "idp" { + count = local.create_config ? 1 : 0 + + metadata { + name = local.idp_secret_name + namespace = var.namespace_name + } + + data = { + client_id = local.idp_config.client_id + client_secret = local.idp_config.client_secret + } +} + +locals { + create_config = true + idp_secret_name = "idp" + idp_config = try(coalesce(local.idp_azure), null) + idp_azure = var.idp_azure != null ? { + provider = "azure" + client_id = var.idp_azure.client_id + client_secret = var.idp_azure.client_secret + url = "https://login.microsoftonline.com/${var.idp_azure.tenant_id}/v2.0" + } : null +} diff --git a/ingress-controller/terraform/crd.tf b/ingress-controller/terraform/crd.tf index 11ffcca..27a8106 100644 --- a/ingress-controller/terraform/crd.tf +++ b/ingress-controller/terraform/crd.tf @@ -1,3 +1,4 @@ -resource "kubernetes_manifest" "pomerium_crd" { - manifest = yamldecode(file("${path.module}/crd.yaml")) +resource "kubectl_manifest" "pomerium_crd" { + yaml_body = file("${path.module}/crd.yaml") } + diff --git a/ingress-controller/terraform/deployment.tf b/ingress-controller/terraform/deployment.tf index 869320b..db42952 100644 --- a/ingress-controller/terraform/deployment.tf +++ b/ingress-controller/terraform/deployment.tf @@ -35,7 +35,7 @@ resource "kubernetes_deployment" "pomerium" { run_as_non_root = true } - node_selector = merge(local.default_node_selector, var.node_selector) + node_selector = local.node_selector container { name = "pomerium-ingress-controller" diff --git a/ingress-controller/terraform/locals.tf b/ingress-controller/terraform/locals.tf index c88f20a..49bdf45 100644 --- a/ingress-controller/terraform/locals.tf +++ b/ingress-controller/terraform/locals.tf @@ -3,6 +3,8 @@ locals { "kubernetes.io/os" = "linux" } + node_selector = merge(local.default_node_selector, var.node_selector) + secrets_name = "bootstrap" default_labels = { diff --git a/ingress-controller/terraform/providers.tf b/ingress-controller/terraform/providers.tf index adb432f..0199da8 100644 --- a/ingress-controller/terraform/providers.tf +++ b/ingress-controller/terraform/providers.tf @@ -1,4 +1,5 @@ terraform { + required_version = ">= 0.13" required_providers { tls = { source = "hashicorp/tls" @@ -14,5 +15,10 @@ terraform { source = "hashicorp/random" version = "~> 3.0" } + + kubectl = { + source = "gavinbunney/kubectl" + version = ">= 1.7.0" + } } } diff --git a/ingress-controller/terraform/variables.tf b/ingress-controller/terraform/variables.tf index add5549..7eb41d2 100644 --- a/ingress-controller/terraform/variables.tf +++ b/ingress-controller/terraform/variables.tf @@ -1,3 +1,4 @@ +# Installation Customization variable "namespace_name" { description = "The name of the namespace to create" type = string @@ -205,3 +206,21 @@ variable "node_selector" { type = map(string) default = {} } + +# Configuration Customization +variable "access_log_fields" { + description = "Access log fields" + type = list(string) + default = null +} + +variable "idp_azure" { + description = "Microsoft EntraID (Azure AD)" + type = object({ + client_id = string + client_secret = string + tenant_id = string + }) + sensitive = true + default = null +} From ce23877ac5bef63e982014008438ecb0f29ed580 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Thu, 31 Oct 2024 18:07:30 -0400 Subject: [PATCH 6/8] pass config params --- ingress-controller/terraform/config.tf | 37 +++----------- ingress-controller/terraform/deployment.tf | 7 ++- ingress-controller/terraform/outputs.tf | 6 +++ ingress-controller/terraform/variables.tf | 56 ++++++++++++++++------ 4 files changed, 60 insertions(+), 46 deletions(-) create mode 100644 ingress-controller/terraform/outputs.tf diff --git a/ingress-controller/terraform/config.tf b/ingress-controller/terraform/config.tf index 04dd116..ab0f67f 100644 --- a/ingress-controller/terraform/config.tf +++ b/ingress-controller/terraform/config.tf @@ -1,5 +1,5 @@ resource "kubectl_manifest" "pomerium_config" { - count = local.create_config ? 1 : 0 + count = local.config != null ? 1 : 0 depends_on = [kubectl_manifest.pomerium_crd] yaml_body = yamlencode({ @@ -8,39 +8,14 @@ resource "kubectl_manifest" "pomerium_config" { metadata = { name = "${var.pomerium_config_name}" } - spec = { - secrets = "${var.namespace_name}/${local.secrets_name}" - identityProvider = local.idp_config != null ? { - provider = local.idp_config.provider - secret = "${var.namespace_name}/${local.idp_secret_name}" - url = local.idp_config.url - } : null - } + spec = local.config }) } -resource "kubernetes_secret" "idp" { - count = local.create_config ? 1 : 0 - - metadata { - name = local.idp_secret_name - namespace = var.namespace_name - } - - data = { - client_id = local.idp_config.client_id - client_secret = local.idp_config.client_secret +locals { + default_config = { + secrets = "${var.namespace_name}/${local.secrets_name}" } -} -locals { - create_config = true - idp_secret_name = "idp" - idp_config = try(coalesce(local.idp_azure), null) - idp_azure = var.idp_azure != null ? { - provider = "azure" - client_id = var.idp_azure.client_id - client_secret = var.idp_azure.client_secret - url = "https://login.microsoftonline.com/${var.idp_azure.tenant_id}/v2.0" - } : null + config = var.config != null ? merge(local.default_config, var.config) : null } diff --git a/ingress-controller/terraform/deployment.tf b/ingress-controller/terraform/deployment.tf index db42952..7d86f5d 100644 --- a/ingress-controller/terraform/deployment.tf +++ b/ingress-controller/terraform/deployment.tf @@ -11,7 +11,12 @@ resource "kubernetes_deployment" "pomerium" { lifecycle { ignore_changes = [ - metadata[0].annotations + metadata[0].annotations, + spec[0].template[0].metadata[0].annotations, + spec[0].template[0].spec[0].container[0].resources, + spec[0].template[0].spec[0].container[0].security_context, + spec[0].template[0].spec[0].toleration, + spec[0].template[0].spec[0].security_context, ] } diff --git a/ingress-controller/terraform/outputs.tf b/ingress-controller/terraform/outputs.tf new file mode 100644 index 0000000..d422261 --- /dev/null +++ b/ingress-controller/terraform/outputs.tf @@ -0,0 +1,6 @@ +output "bootstrap_secret" { + value = { + name = kubernetes_secret.bootstrap.metadata[0].name + namespace = kubernetes_secret.bootstrap.metadata[0].namespace + } +} diff --git a/ingress-controller/terraform/variables.tf b/ingress-controller/terraform/variables.tf index 7eb41d2..b5a9249 100644 --- a/ingress-controller/terraform/variables.tf +++ b/ingress-controller/terraform/variables.tf @@ -207,20 +207,48 @@ variable "node_selector" { default = {} } -# Configuration Customization -variable "access_log_fields" { - description = "Access log fields" - type = list(string) - default = null -} - -variable "idp_azure" { - description = "Microsoft EntraID (Azure AD)" +variable "config" { + description = "Pomerium configuration. Set to null to disable config creation. See https://www.pomerium.com/docs/k8s/reference" type = object({ - client_id = string - client_secret = string - tenant_id = string + accessLogFields = optional(list(string)) + authenticate = optional(object({ + callbackPath = optional(string) + url = string + })) + caSecrets = optional(list(string)) + certificates = optional(list(string)) + cookie = optional(object({ + domain = optional(string) + expire = optional(string) + httpOnly = optional(bool) + name = optional(string) + sameSite = optional(string) + })) + identity_provider = optional(object({ + provider = string + requestParams = optional(map(string)) + requestParamsSecret = optional(string) + scopes = optional(list(string)) + secret = string + url = optional(string) + })) + jwtClaimsHeaders = optional(map(string)) + passIdentityHeaders = optional(bool) + programmaticRedirectDomains = optional(string) + runtimeFlags = optional(map(bool)) + storage = optional(object({ + postgres = object({ + caSecret = optional(string) + secret = string + tlsSecret = optional(string) + }) + })) + timeouts = optional(object({ + idle = optional(string) + read = optional(string) + write = optional(string) + })) + useProxyProtocol = optional(bool) }) - sensitive = true - default = null + default = {} } From 77cbb6c099e02a097663be2d860aecfb307bc944 Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Tue, 5 Nov 2024 15:46:47 -0500 Subject: [PATCH 7/8] cr comments --- ingress-controller/kustomize/crd/bases/README.md | 1 + ....io_pomerium.yaml.yaml => ingress.pomerium.io_pomerium.yaml} | 0 ingress-controller/terraform/crd.yaml | 2 +- 3 files changed, 2 insertions(+), 1 deletion(-) rename ingress-controller/kustomize/crd/bases/{ingress.pomerium.io_pomerium.yaml.yaml => ingress.pomerium.io_pomerium.yaml} (100%) diff --git a/ingress-controller/kustomize/crd/bases/README.md b/ingress-controller/kustomize/crd/bases/README.md index e69de29..6dc7b10 100644 --- a/ingress-controller/kustomize/crd/bases/README.md +++ b/ingress-controller/kustomize/crd/bases/README.md @@ -0,0 +1 @@ +Origin: https://github.com/pomerium/ingress-controller/tree/main/config/crd/bases diff --git a/ingress-controller/kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml.yaml b/ingress-controller/kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml similarity index 100% rename from ingress-controller/kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml.yaml rename to ingress-controller/kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml diff --git a/ingress-controller/terraform/crd.yaml b/ingress-controller/terraform/crd.yaml index 72566dc..c477f41 120000 --- a/ingress-controller/terraform/crd.yaml +++ b/ingress-controller/terraform/crd.yaml @@ -1 +1 @@ -../kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml.yaml \ No newline at end of file +../kustomize/crd/bases/ingress.pomerium.io_pomerium.yaml \ No newline at end of file From 7b49cfa6a0d2d0f80c2425838fdbdd525397d7fe Mon Sep 17 00:00:00 2001 From: Denis Mishin Date: Tue, 5 Nov 2024 15:50:20 -0500 Subject: [PATCH 8/8] update readme --- ingress-controller/terraform/README.md | 29 ++++---------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/ingress-controller/terraform/README.md b/ingress-controller/terraform/README.md index 7e030f1..6c10580 100644 --- a/ingress-controller/terraform/README.md +++ b/ingress-controller/terraform/README.md @@ -1,33 +1,12 @@ -This Terraform module installs +This Terraform module installs the Pomerium Ingress Controller. -```terraform -provider "kubernetes" { - -} +Docs: https://www.pomerium.com/docs/deploying/k8s/install +```terraform module "pomerium_ingress_controller" { source = "git:https://github.com/pomerium/install//ingress-controller/terraform?ref=REF" } ``` -Where `REF` may be an individual commit, a branch (i.e. `main`) or version tag (i.e. `v0.27.2`). - -Once Pomerium Ingress Controller is installed, you may reference additional configurations via the `Pomerium` CRD. -See https://www.pomerium.com/docs/k8s/configure +Where `REF` may be an individual commit, a branch (i.e. `main`) or version tag (i.e. `v0.28.0`). -As it has to reference a CRD that does not exist until installed, the configuration manifest has to be created part of a separate Terraform run. - -```terraform -resource "kubernetes_manifest" "pomerium_config" { - manifest = { - apiVersion = "ingress.pomerium.io/v1" - kind = "Pomerium" - metadata = { - name = "global" - } - spec = { - secrets = "pomerium-ingress-controller/bootstrap" - } - } -} -```