Adding TLS Certificates to Your TrueFoundry Deployment
This guide explains how to configure TLS certificates to enable HTTPS access to your TrueFoundry deployments. We’ll cover multiple approaches based on your cloud and DNS provider.- AWS
- GCP
- Azure
- Cert files
When running TrueFoundry on AWS EKS, you have two options for TLS termination:
Terminate TLS at the Network Load Balancer using AWS cert-manager (recommended)
Terminate TLS at the Network Load Balancer using AWS cert-manager (recommended)
For production AWS deployments, terminating TLS at the Network Load Balancer using AWS Certificate Manager (ACM) is recommended for best performance and manageability.
Creating the certificate in AWS Certificate Manager
-
Create a certificate in ACM:
- Navigate to AWS Certificate Manager in the AWS console
- Request a public certificate
- Specify your domain (e.g.,
*.tfy.example.com) - Choose DNS validation (recommended)
-
Validate domain ownership:
-
Add the CNAME records provided by ACM to your DNS provider
- Follow the official AWS guide for DNS validation
- For detailed steps on adding CNAME records, see AWS documentation on DNS validation
- Wait for the certificate to change to “Active” status (this may take 30 minutes or longer)
-
Copy the certificate ARN for the next step (format will be like:
arn:aws:acm:region:account:certificate/certificate-id)
-
Add the CNAME records provided by ACM to your DNS provider
Applying the certificate to your TrueFoundry deployment
- In the TrueFoundry platform, navigate to Deployments > Helm
- Filter to find the helm chart for your cluster and select tfy-istio-ingress helm chart.
-
Click Edit and update the configuration:
CopyAsk AI
gateway: annotations: service.beta.kubernetes.io/aws-load-balancer-ssl-cert: <your-certificate-arn-here>
Terminate TLS using cert-manager with your DNS provider (e.g. cloudflare, godaddy, etc.)
Terminate TLS using cert-manager with your DNS provider (e.g. cloudflare, godaddy, etc.)
Other way to handle TLS termination is to use cert-manager with your DNS provider. This is useful if you don’t want to use AWS cert-manager.For this you can follow the instructions here.
When running TrueFoundry on GCP, you have the following options for TLS termintation
Terminate TLS by using cert-manager with GCP Cloud DNS (recommended)
Terminate TLS by using cert-manager with GCP Cloud DNS (recommended)
For production GCP deployments, we recommend using cert-manager with GCP Cloud DNS. This helps in ensuring that the domain you are using for TrueFoundry’s deployment is separate from your main domain. It also helps in managing the certificates and renewals automatically. If you want to use your own DNS provider with cert-manager, you can follow the instructions here.Add the nameservers from the output to your domain registrar (GoDaddy, Namecheap, etc.) so that this DNS zone is now used for your domain.
Creating the certificate using cert-manager with GCP Cloud DNS
This approach requires workload identity to be enabled on your GKE cluster. For clusters created through Terraform code generated by TrueFoundry, this is enabled by default.Step 1: Configure GCP Service Account and Permissions
Copy
Ask AI
# Set your variables
export CLUSTER_NAME="<your-gke-cluster>"
export CLUSTER_LOCATION="<your-cluster-zone>" #(us-central1)
export DNS_ROLE_NAME="<cert_manager_dns_role>" # role name for cert-manager to use in GCP
export GCP_SERVICEACCOUNT_NAME="cert-manager-dns"
export MAIL_ID="<your-email@example.com>"
export PROJECT_ID=$(gcloud config get-value project) # set your project ID here
export LOAD_BALANCERIP=$(kubectl get svc -n istio-system tfy-istio-ingress -ojsonpath='{.status.loadBalancer.ingress[0].ip}')
# Verify values
echo "PROJECT_ID: ${PROJECT_ID}"
echo "CLUSTER_NAME: ${CLUSTER_NAME}"
echo "CLUSTER_LOCATION: ${CLUSTER_LOCATION}"
echo "LOAD_BALANCERIP: ${LOAD_BALANCERIP}"
# Set project
gcloud config set project $PROJECT_ID
# Create service account
gcloud iam service-accounts create $GCP_SERVICEACCOUNT_NAME --display-name "$GCP_SERVICEACCOUNT_NAME"
# Create custom role with minimal DNS permissions
gcloud iam roles create custom_dns_role --project=$PROJECT_ID --title=$DNS_ROLE_NAME \
--permissions=dns.resourceRecordSets.create,dns.resourceRecordSets.delete,dns.resourceRecordSets.get,dns.resourceRecordSets.list,dns.resourceRecordSets.update,dns.changes.create,dns.changes.get,dns.changes.list,dns.managedZones.list
# Bind role to service account
gcloud projects add-iam-policy-binding $PROJECT_ID \
--condition=None \
--member=serviceAccount:$GCP_SERVICEACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com \
--role="projects/$PROJECT_ID/roles/custom_dns_role"
# Allow cert-manager to use the service account through workload identity
gcloud iam service-accounts add-iam-policy-binding --role roles/iam.workloadIdentityUser \
--member "serviceAccount:$PROJECT_ID.svc.id.goog[cert-manager/cert-manager]" \
$GCP_SERVICEACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
Step 2: Configure DNS for Your Domain
If you already have a DNS zone in GCP, you can skip the step of creating the DNS zone and simply assign the variablesDNS_HOSTED_ZONE and DNS_ZONE_PROJECT_ID with the name of your DNS zone and the project ID respectively.Copy
Ask AI
# Set DNS zone name
export DNS_HOSTED_ZONE="tfy.example.com"
export DNS_ZONE_PROJECT_ID="${PROJECT_ID}"
# Create DNS zone (if it doesn't exist)
gcloud dns managed-zones create example-com --project=${DNS_ZONE_PROJECT_ID} \
--description="DNS zone for ${DNS_HOSTED_ZONE}" \
--dns-name=${DNS_HOSTED_ZONE} \
--visibility=public
# Get nameservers
gcloud dns managed-zones describe example-com \
--format="json" | jq -r '.nameServers[]'
Step 3: Install and Configure cert-manager
From the platform, head over to the Cluster’s page and ensure that you havecert-manager addon installed. Ensure that you are passing the google serviceaccount email to the cert-manager serviceaccount annotations in the values section.Copy
Ask AI
cert-manager:
serviceAccount:
annotations:
iam.gke.io/gcp-service-account: $GCP_SERVICEACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
Step 4: Create Certificate Issuer and Request Certificate
-
Get your cluster credentials:
CopyAsk AI
gcloud container clusters get-credentials $CLUSTER_NAME --zone $CLUSTER_LOCATION --project $PROJECT_ID -
Create an issuer for Let’s Encrypt.
CopyAsk AI
kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: letsencrypt-issuer namespace: istio-system spec: acme: email: $MAIL_ID server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-key solvers: - dns01: cloudDNS: project: $DNS_ZONE_PROJECT_ID EOF -
Request a certificate. You can replace the
.metadata.nameof the certificate and the.spec.secretNameaccordingly. Ensure that you have also replaced the.spec.issuerRef.namewith the name of the issuer you created in the previous step and the.spec.dnsNameswith your chosen domain name. Here we are usingexample.comand*.example.comas the domain names.CopyAsk AIkubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: example-com-cert namespace: istio-system spec: secretName: example-com-tls duration: 2160h # 90d renewBefore: 360h # 15d issuerRef: name: letsencrypt-issuer dnsNames: - "tfy.example.com" - "*.tfy.example.com" EOF -
Check certificate status:
CopyAsk AI
kubectl get certificates -n istio-systemTroubleshooting
If the certificate remains in a non-ready state for more than 10 minutes, check the cert-manager logs:ShellCopyAsk AIkubectl logs -n cert-manager -l app=cert-manager
Step 5: Configure TLS in Your Ingress Gateway
Once the certificate is created, head over to the cluster’s page and navigate to thetfy-istio-ingress addon. Add the secret name in the tfyGateway.spec.servers[1].tls.credentialName section and ensure that tfyGateway.spec.servers[1].port.protocol is set to HTTPS. Here we are using example-com-tls as the secret name which contains the certificate and key.Copy
Ask AI
servers:
- <REDACTED>
- hosts:
- "*"
port:
name: https-tfy-wildcard
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: example-com-tls
Terminate TLS by using cert-manager with your DNS provider (e.g. Route 53, cloudflare, godaddy, etc.)
Terminate TLS by using cert-manager with your DNS provider (e.g. Route 53, cloudflare, godaddy, etc.)
Other way to handle TLS termination is to use cert-manager with your DNS provider. This is useful if you don’t want to use GCP Cloud DNS.
For this you can follow the instructions here.
When running TrueFoundry on Azure, you have the following options for TLS termintation
Terminate TLS by using cert-manager with Azure DNS zone (recommended)
Terminate TLS by using cert-manager with Azure DNS zone (recommended)
For production Azure deployments, we recommend using cert-manager with Azure DNS. This helps in ensuring that the domain you are using for TrueFoundry’s deployment is separate from your main domain. It also helps in managing the certificates and renewals automatically. If you want to use your own DNS provider with cert-manager, you can follow the instructions here.Add the nameservers from the output to your domain registrar (GoDaddy, Namecheap, etc.) so that this DNS zone is now used for your domain.
Creating the certificate using cert-manager with Azure DNS zone
This approach requires workload identity to be enabled on your AKS cluster. For clusters created through Terraform code generated by TrueFoundry, this is enabled by default.Step 1: Configure user identity and permissions
Copy
Ask AI
# Set your variables
export CLUSTER_NAME="<your-aks-cluster>"
export RESOURCE_GROUP="<your-resource-group>"
export AZURE_SUBSCRIPTION_ID="<your-subscription-id>"
export SERVICE_ACCOUNT_NAME=cert-manager
export SERVICE_ACCOUNT_NAMESPACE=cert-manager
export MAIL_ID="<your-email@example.com>"
# Get OIDC issuer URL and load balancer IP
export OIDC_ISSUER_URL=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)
export LOAD_BALANCERIP=$(kubectl get svc -n istio-system tfy-istio-ingress -ojsonpath='{.status.loadBalancer.ingress[0].ip}')
# Create and get managed identity
export IDENTITY_NAME="$CLUSTER_NAME"
# Create managed identity and get IDs
PRINCIPAL_ID=$(az identity create --name "${IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --query principalId -otsv)
IDENTITY_CLIENT_ID=$(az identity show --name "${IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --query 'clientId' -otsv)
# Verify values
echo "PRINCIPAL_ID: ${PRINCIPAL_ID}"
echo "IDENTITY_CLIENT_ID: ${IDENTITY_CLIENT_ID}"
echo "OIDC_ISSUER_URL: ${OIDC_ISSUER_URL}"
echo "LOAD_BALANCERIP: ${LOAD_BALANCERIP}"
Step 2: Configure DNS Zone and Permissions
If you already have a DNS zone in Azure, you can skip the step of creating the DNS zone and simply assign the variablesDNS_HOSTED_ZONE and DNS_ZONE_RESOURCE_GROUP with the name of your DNS zone and the resource group respectively. Run the remaining commands to assign permissions and set up federated credentials.Copy
Ask AI
# Set DNS zone name
export DNS_HOSTED_ZONE="tfy.example.com"
export DNS_ZONE_RESOURCE_GROUP="${RESOURCE_GROUP}"
# Create DNS zone
az network dns zone create --name ${DNS_HOSTED_ZONE} --resource-group ${DNS_ZONE_RESOURCE_GROUP} --query nameServers
# Get the DNS zone ID
DNS_ZONE_ID=$(az network dns zone show --name ${DNS_HOSTED_ZONE} --resource-group ${DNS_ZONE_RESOURCE_GROUP} --query id -otsv)
# Assign permissions
az role assignment create --assignee $PRINCIPAL_ID --role "DNS Zone Contributor" --scope $DNS_ZONE_ID
# Set up federated credentials
az identity federated-credential create --name "cert-manager" --identity-name "${IDENTITY_NAME}" --issuer "${OIDC_ISSUER_URL}" --resource-group "${RESOURCE_GROUP}" --subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
Step 3: Install and Configure cert-manager
From the platform, head over to the Cluster’s page and ensure that you havecert-manager addon installed. Ensure that you are passing the right pod and serviceAccount labels for cert-manager to use workload identity. These will be present if cert-manager is installed through TrueFoundry’s Addon/Helm section.Copy
Ask AI
installCRDs: true
extraArgs:
- --issuer-ambient-credentials
podLabels:
azure.workload.identity/use: "true"
serviceAccount:
labels:
azure.workload.identity/use: "true"
Step 4: Create Certificate Issuer and Request Certificate
-
Get your cluster credentials:
CopyAsk AI
az aks get-credentials --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP -
Create an issuer.
CopyAsk AI
kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: azure-issuer namespace: istio-system spec: acme: email: $MAIL_ID server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: azure-issuer-key solvers: - dns01: azureDNS: hostedZoneName: $DNS_HOSTED_ZONE resourceGroupName: $DNS_ZONE_PROJECT_ID subscriptionID: $AZURE_SUBSCRIPTION_ID environment: AzurePublicCloud managedIdentity: clientID: $IDENTITY_CLIENT_ID EOF -
Request a certificate. You can replace the
.metadata.nameof the certificate and the.spec.secretNameaccordingly. Ensure that you have also replaced the.spec.issuerRef.namewith the name of the issuer you created in the previous step and the.spec.dnsNameswith your chosen domain name. Here we are usingexample.comand*.example.comas the domain names.CopyAsk AIkubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: example-cert namespace: istio-system spec: secretName: example-com-tls duration: 2160h # 90d renewBefore: 360h # 15d issuerRef: name: azure-issuer dnsNames: - "example.com" - "*.example.com" EOF -
Check certificate status:
CopyAsk AI
kubectl get certificates -n istio-systemTroubleshooting
If the certificate remains in a non-ready state for more than 10 minutes, check the cert-manager logs:ShellCopyAsk AIkubectl logs -n cert-manager -l app=cert-manager
Step 5: Configure TLS in Your Ingress Gateway
Once the certificate is created, head over to the cluster’s page and navigate to thetfy-istio-ingress addon. Add the secret name in the tfyGateway.spec.servers[1].tls.credentialName section and ensure that tfyGateway.spec.servers[1].port.protocol is set to HTTPS. Here we are using example-com-tls as the secret name which contains the certificate and key.Copy
Ask AI
servers:
- <REDACTED>
- hosts:
- "*"
port:
name: https-tfy-wildcard
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: example-com-tls
Terminate TLS by using cert-manager with your DNS provider (e.g. Route 53, cloudflare, godaddy, etc.)
Terminate TLS by using cert-manager with your DNS provider (e.g. Route 53, cloudflare, godaddy, etc.)
Other way to handle TLS termination is to use cert-manager with your DNS provider. This is useful if you don’t want to use Azure DNS.
For this you can follow the instructions here.
If you have your own certificate files (e.g., from another certificate provider or self-signed), you can use them directly with TrueFoundry.
-
Create a Kubernetes secret with your certificate and key or create a self-signed certificate:
CopyAsk AI
# Generate a self-signed certificate openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout tls.key -out tls.crt \ -subj "/CN=*.example.com" \ -addext "subjectAltName = DNS:example.com,DNS:*.example.com"CopyAsk AI# Create secret from local certificate files kubectl create secret tls example-com-tls \ --cert=path/to/cert/file \ --key=path/to/key/file \ -n istio-system -
Once the secret is created, head over to the cluster’s page and navigate to the
tfy-istio-ingressaddon. Add the secret name in thetfyGateway.spec.servers[1].tls.credentialNamesection and ensure thattfyGateway.spec.servers[1].port.protocolis set toHTTPS. Here we are usingexample-com-tlsas the secret name which contains the certificate and key.CopyAsk AIservers: - <REDACTED> - hosts: - "*" port: name: https-tfy-wildcard number: 443 protocol: HTTPS tls: mode: SIMPLE credentialName: example-com-tls
Self-signed certificates will cause browser warnings. They should only be used for testing or internal systems. To connect to services with self-signed certificates, you have to pass the CA certificate to verify the SSL certificate.