- Install Helm (v3+)
- Kubernetes (v1.14+)
Deploy Infra via helm
:
helm repo add infrahq https://infrahq.github.io/helm-charts
helm repo update
Create an initial values.yaml
:
server:
service:
type: LoadBalancer
Deploy the Helm chart:
helm install infra-server infrahq/infra-server -f values.yaml
Find your admin credentials:
kubectl get secret infra-server-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d
Find your Load Balancer endpoint:
kubectl get service infra-server -o jsonpath="{.status.loadBalancer.ingress[*]['ip', 'hostname']}"
Depending on where you are hosting your cluster, the creation of the load balancer can take 10 minutes or more by a cloud provider.
Download the Infra CLI and log in with user admin@local
:
export INFRA_SERVER=<your self-hosted server endpoint>
export INFRA_USER=admin@local
infra login $INFRA_SERVER
export INFRA_ACCESS_KEY=$(infra keys add --connector -q)
Install Infra connector via helm:
helm install infra infrahq/infra --set config.server.url=$INFRA_SERVER --set config.accessKey=$INFRA_ACCESS_KEY --set config.name=example
It may take a few minutes for your cluster to connect. To avoid TLS certificate errors, make sure you run Infra behind an ingress controller below with certificates configured.
To finish, verify that your cluster is connected:
infra destinations list
Infra supports multiple configuration methods for connecting Kubernetes clusters. Please follow the Kubernetes guide.
This section outlines how to set up Infra programatically using the Infra Terraform Provider.
Start by adding the Helm chart:
helm repo add infrahq https://infrahq.github.io/helm-charts
helm repo update
Generate a pre-defined admin access key:
export INFRA_ACCESS_KEY="$(openssl rand -hex 5).$(openssl rand -hex 12)"
Create a Kubernetes secret for the access key:
kubectl create secret generic infra-admin-access-key --from-literal=access-key=$INFRA_ACCESS_KEY
Configure an initial values.yaml
file to use this admin access key:
config:
admin:
enable: true
accessKeySecret: infra-admin-access-key
server:
service:
type: LoadBalancer
Then deploy the Infra server:
helm install infra-server infrahq/infra-server -f values.yaml
Retrieve your Infra server endpoint:
export INFRA_SERVER_HOST=$(kubectl get service infra-server -o jsonpath="{.status.loadBalancer.ingress[*]['ip', 'hostname']}")
Finally, use this access key in Terraform to set up providers
and grants
:
terraform {
required_providers {
infra = {
source = "infrahq/infra"
}
}
}
# Configure Infra Terraform provider.
provider "infra" {
access_key = "$INFRA_ACCESS_KEY"
host = "$INFRA_SERVER_HOST"
}
resource "infra_identity_provider" "okta" {
client_id = "0oa2hl2inow5Uqc6c357"
client_secret = "lj1aj801208sdjf19820d122jhaljksdamkj0"
okta {
issuer = "example.okta.com"
}
}
resource "infra_grant" "kubernetes_admin" {
user_name = "[email protected]"
kubernetes {
cluster = "my_cluster"
role = "admin"
}
}
And then run terraform plan
or terraform apply
:
terraform apply
To disable the admin user in the Helm chart, update your values file:
config:
admin:
enabled: false
Remove the admin access key:
kubectl delete secret infra-admin-access-key
Lastly, delete the generated admin user from Infra:
infra users remove admin@local
Infra uses PostgreSQL as a data store, and the Infra server helm chart includes a PostgreSQL deployment. If you use an external database please be aware of the following.
Infra is tested to work with the latest patch release of PostgreSQL 12.x and PostgreSQL 14.x. Other versions may work, but are not tested.
Infra requires a dedicated database connection for every Infra connector, plus a few more
connections to handle other requests. It is important to ensure the postgres database
max_connections
is set accordingly, and also that the number of open connections is monitored.
Refer to the Helm chart documentation for a full list of customization options.
To expose the Infra server externally via a load balancer service:
# example values.yaml
---
server:
service:
type: LoadBalancer
# example values.yaml
---
server:
service:
annotations:
# If using Google GKE
cloud.google.com/load-balancer-type: Internal
# If using AWS EKS
service.beta.kubernetes.io/aws-load-balancer-scheme: internal
# If using Azure AKS
service.beta.kubernetes.io/azure-load-balancer-internal: true
# example values.yaml
---
server:
service:
annotations:
# If using AWS EKS
service.beta.kubernetes.io/aws-load-balancer-healthcheck-protocol: HTTPS
service.beta.kubernetes.io/aws-load-balancer-healthcheck-path: /healthz
# If using Azure AKS
service.beta.kubernetes.io/azure-load-balancer-health-probe-protocol: https # Kubernetes 1.20+
service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: healthz # Kubernetes 1.20+
# If using Digital Ocean
service.beta.kubernetes.io/do-loadbalancer-healthcheck-protocol: https
service.beta.kubernetes.io/do-loadbalancer-healthcheck-path: /healthz
Infra server can be configured to expose port 80 (HTTP) and 443 (HTTPS). Use the following Ingress controller specific examples to configure Infra Server Ingress.
Infra connectors make long polling requests to the infra server. These requests may sit idle for up to 5 minutes while waiting for updates. The ingress must be configured with a timeout of at least 305 seconds to avoid 504 timeout errors from the connector.
# example values.yaml
---
server:
service:
type: ClusterIP
annotations:
getambassador.io/config: |-
apiVersion: getambassador.io/v2
kind: Mapping
name: infra-https-mapping
namespace: infrahq
host: infrahq.example.com # edit me
prefix: /
service: http://infra
timeout_ms: 305000
idle_timeout_ms: 305000
# example values.yaml
---
server:
ingress:
enabled: true
hosts:
- infra.example.com # edit me
className: alb
paths:
- '/*'
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing # (optional: use "internal" for non-internet facing)
alb.ingress.kubernetes.io/backend-protocol: HTTP
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/group.name: infra # (optional: edit me to use an existing shared load balanacer)
# example values.yaml
---
server:
ingress:
enabled: true
hosts:
- infra.example.com # edit me
servicePort: 80
className: nginx
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
nginx.ingress.kubernetes.io/backend-protocol: 'HTTP'
nginx.ingress.kubernetes.io/proxy-http-version: '1.0'
cert-manager.io/issuer: 'letsencrypt-prod' # edit me
nginx.ingress.kubernetes.io/proxy-send-timeout: '305'
nginx.ingress.kubernetes.io/proxy-read-timeout: '305'
tls:
- hosts:
- infra.example.com # edit me
secretName: com-example-infra # edit me
# example values.yaml
---
server:
serviceAccount:
annotations:
# Google Workload Identity
# https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity
iam.gke.io/gcp-service-account: <GSA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com
# AWS Service Account Role
# https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html
eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/<IAM_ROLE_NAME>
helm uninstall infra-server
To pin a specific version from Infra's homebrew tap, use brew pin
:
# Get the infra.rb file from the homebrew tap repo (e.g. here for 0.15.2)
curl https://raw.githubusercontent.com/infrahq/homebrew-tap/286489abe6266d3af9d19e364bacf9b960f8e696/infra.rb -o infra.rb
# install `infra` from this version
brew install infra.rb
# pin the version for now (i.e. don't auto upgrade)
brew pin infra