Skip to main content

tare gateway install

Install serve gateway resources. The provider is selected with --type (gcp, azure, or aws).


Synopsis

tare gateway install <identity-file> [flags]

Description

tare gateway install deploys the gateway chart used to expose serve traffic.

High-level workflow:

  1. Load identity file
  2. Load optional gcp-gateway.json config (--config)
  3. Resolve values from flags/config/identity (with provenance: every resolved value carries the source it came from)
  4. Plan: render a diff between the resolved config and live GCP/k8s state, with inline lint findings and a customer-action block; in a TTY, prompt Proceed? [y/N]. CI callers pass --yes.
  5. Optional prereq workflow (--dry-run-prereqs or --apply-prereqs)
  6. Run preflight checks
  7. Install chart with Helm
  8. Optional wait for Gateway address (--wait) and print DNS A-record action

The Plan view is the same JSON contract (apiVersion: tare.tetrate.io/v1alpha1) used by tare gateway config lint; use --plan-only --output json to consume it from other tooling.

Plan / Confirm / Apply flags

FlagDescription
--plan-onlyRender the Plan and exit without applying changes.
--yesSkip the interactive Proceed? prompt. Required in non-TTY contexts (CI).
--accept-warningsProceed even when lint warnings are present. Errors still block.
--output text|jsonPlan output format. Default: text.

Provider support:

  • gcp: supported (GCP Cloud Load Balancer + certificate-manager + Helm chart)
  • azure: supported (AKS + AGIC addon + Ingress): traditional Azure CNI only
  • aws: supported (EKS + in-tree Network Load Balancer; no AWS Load Balancer Controller, no aws CLI)

Prerequisites

Before install, you must either:

  • run --apply-prereqs, or
  • confirm prerequisites are already done with --ack-prereqs

GCP prerequisites

Expected prerequisites:

  • wildcard DNS prepared for your serve hostname
  • TLS certificate + certificate map prepared
  • static IP / cloud policy resources prepared

If --apply-prereqs is used, gcloud must be installed and authenticated.

Azure prerequisites

Expected prerequisites:

  • AKS cluster exists with AGIC-compatible networking (networkPlugin: azure, networkPluginMode: null, networkDataplane: azure)
  • az CLI installed and az login completed
  • signed-in identity has the required Azure roles (see below)
  • kubectl context points at the target AKS cluster

If --apply-prereqs is used, the install runs az aks enable-addons --addons ingress-appgw (which provisions an Application Gateway, ~5min) before applying the Ingress.

Pre-flights that run before any side effects:

  • AGIC networking compatibility: az aks show ... --query networkProfile must report {plugin: azure, mode: null, dataplane: azure}. If the cluster is Cilium/Overlay, fails fast with a pointer to AGC follow-up.
  • Azure RBAC: checks Azure Kubernetes Service Contributor Role on the AKS RG and Network Contributor on the MC_<rg>_<cluster>_<region> node-RG. Missing roles fail with the exact az role assignment create command to fix. If Microsoft.Authorization/roleAssignments/read is itself denied, the pre-flight degrades to a warning and proceeds (the install will surface AuthorizationFailed itself if a role is genuinely missing).
  • Kubernetes RBAC: kubectl auth can-i create ingress -n tars-dataplane. Fails with a hint pointing at the edit ClusterRole if denied.

AWS prerequisites

The AWS path is ingress-only and the lightest of the three. It exposes the data plane's egress as a Network Load Balancer by setting envoyService.type=LoadBalancer plus the NLB annotation on the egress EnvoyProxy (tars-egress-proxy in tars-system). The egress Service is Envoy-Gateway-managed, so driving the load balancer through the EnvoyProxy is durable: Envoy Gateway re-asserts the NLB across pod restarts, Envoy Gateway restarts, and tare upgrade. A direct Service patch reverts to ClusterIP on the next reconcile. The in-tree EKS cloud provider provisions the NLB from the annotation, so no AWS Load Balancer Controller and no aws CLI are required, and there is no prereq workflow (--apply-prereqs and --ack-prereqs do not apply).

Expected prerequisites:

  • EKS cluster with the data plane already installed (tare install), so the egress EnvoyProxy exists in tars-system
  • kubectl context points at the target EKS cluster

Pre-flights that run after the Plan and confirmation, before any mutation:

  • kubectl / cluster reachable
  • egress EnvoyProxy exists in the system namespace. Fails with an "is the data plane installed?" hint; override the name with --aws-envoyproxy if it differs.
  • Kubernetes RBAC: kubectl auth can-i patch envoyproxies.gateway.envoyproxy.io -n tars-system. Fails with a hint pointing at the needed role if denied.

Identity for credential-less upstream auth (Bedrock, for example) is a separate step; see Bedrock workload identity. This command only exposes the gateway.

Config file

Use --config to provide gateway settings:

tare gateway install identity.json --type gcp --config gcp-gateway.json
tare gateway install identity.json --type azure --config azure-gateway.json

Full schemas:

--type aws takes no config file. It is configured entirely by flags (--aws-internal, --aws-service, --aws-envoyproxy).

Usage

Render the Plan and exit

tare gateway install identity.json \
--type gcp \
--config gcp-gateway.json \
--plan-only

Outputs the resolved values (with provenance), the GCP/k8s deltas against live state, inline lint findings, and the customer-action block. No side effects.

tare gateway install identity.json \
--type gcp \
--config gcp-gateway.json \
--print-helm-values

Preview prerequisite gcloud commands

tare gateway install identity.json \
--type gcp \
--config gcp-gateway.json \
--dry-run-prereqs

Apply prerequisites and install

tare gateway install identity.json \
--type gcp \
--config gcp-gateway.json \
--apply-prereqs \
--wait

Install when prereqs are already managed externally

tare gateway install identity.json \
--type gcp \
--config gcp-gateway.json \
--ack-prereqs \
--wait
tare gateway install identity.json \
--type gcp \
--config gcp-gateway.json \
--print-resources

On the Azure path, --print-resources emits the tars-ingress YAML (with the AGIC health-probe annotations) instead of helm-templated chart output. On the AWS path, it emits the EnvoyProxy merge patch (the spec.provider.kubernetes.envoyService block: type: LoadBalancer plus the NLB annotation).

Azure: preview the az plan without applying

tare gateway install identity.json \
--type azure \
--config azure-gateway.json \
--dry-run-prereqs

Azure: apply prerequisites and install

tare gateway install identity.json \
--type azure \
--config azure-gateway.json \
--apply-prereqs --wait

Runs the AGIC compat pre-flight, the Azure RBAC pre-flight (printing remediation commands when needed), and the K8s can-i create ingress pre-flight; then enables the AGIC addon, applies the Ingress with health-probe annotations, waits for the Ingress to report an address, and prints the DNS A-record customer action.

AWS: expose the egress as an NLB

tare gateway install identity.json \
--type aws \
--wait

Renders the Plan (the EnvoyProxy patch), confirms (or --yes in CI), runs the kubectl, cluster, and EnvoyProxy pre-flights, patches the egress EnvoyProxy with envoyService.type=LoadBalancer plus service.beta.kubernetes.io/aws-load-balancer-type=nlb, waits for Envoy Gateway to reconcile the egress Service and the in-tree EKS cloud provider to publish the NLB hostname, then prints the DNS CNAME customer action and a smoke-test curl (expect HTTP 401).

AWS: provision an internal NLB

tare gateway install identity.json \
--type aws \
--aws-internal \
--wait

Adds service.beta.kubernetes.io/aws-load-balancer-internal=true so the NLB is internal-only.

Flags

Main

FlagDefaultDescription
--typegcpGateway provider type (gcp|azure|aws)
--config <file>nonePath to gateway config (gcp-gateway.json or azure-gateway.json; not used by aws)
--project-id <id>from config(GCP) project for prereq automation
--serve-domain <host>from config/serve-urlHostname/domain used by prereq automation
--certificate-name <name>from config(GCP) certificate resource name for managed cert workflow
--dns-authorization-name <name>from config/derived(GCP) DNS authorization resource name
--serve-url <url-or-host>config → identityGateway host override
--certificate-map-name <name>from config(GCP) certificate map name
--static-ip-name <name>from config(GCP) optional static IP resource name
--security-policy <name>from config(GCP) optional Cloud Armor security policy name
--customer <name>identity/configCustomer label
--environment <name>from configEnvironment label (required when customer is saas)
--ack-prereqsfalseConfirm prereqs are already handled
--dry-run-prereqsfalsePrint prereq cloud-CLI plan (gcloud or az)
--apply-prereqsfalseRun prereq cloud-CLI plan
--waitfalseWait until Gateway has an address (Azure: Ingress address; AWS: NLB hostname)

Azure (only consulted under --type azure)

FlagDefaultDescription
--azure-subscription-id <uuid>from configAzure subscription scoping az calls
--azure-resource-group <name>from configResource group holding the AKS cluster
--aks-cluster-name <name>from configAKS cluster name
--appgw-name <name><aks-cluster>-appgwApplication Gateway name AGIC creates
--appgw-subnet-cidr <cidr>10.225.0.0/24App Gateway subnet CIDR

AWS (only consulted under --type aws)

FlagDefaultDescription
--aws-internalfalseProvision an internal NLB (adds the aws-load-balancer-internal annotation)
--aws-service <name>egressEgress Service Envoy Gateway exposes as an NLB
--aws-envoyproxy <name>tars-egress-proxyEgress EnvoyProxy resource to drive the NLB through

Inspect

FlagDefaultDescription
--print-helm-valuesfalsePrint generated Helm values to stdout
--print-resourcesfalsePrint rendered Kubernetes manifests to stdout

Advanced / hidden

FlagDefaultDescription
--timeout10mTimeout for --wait
--release-nametars-gatewayHelm release name
--namespacetars-gatewayHelm release namespace
--system-namespacetars-systemNamespace referenced by gateway routes
--dataplane-namespacetars-dataplaneDataplane namespace referenced by gateway routes
--chart-pathembeddedOverride chart source path/OCI/HTTP
--chart-versionnoneChart version (needed for remote charts)
--helm-valuesnoneExtra Helm values file to merge
--skip-preflightfalseSkip preflight checks

Output behavior

  • Progress and operator guidance are written to stderr
  • --print-helm-values and --print-resources write generated artifacts to stdout

When --wait succeeds, CLI prints:

  • resolved Gateway address
  • customer DNS A-record action (Host, Type A, Value, TTL)
  • certificate provisioning reminder

On the AWS path the resolved address is the NLB hostname, and the customer action is a CNAME record rather than an A record, followed by the smoke-test curl.

Verification

kubectl get gateway -n tars-gateway
kubectl get httproute -n tars-system
kubectl get httproute -n tars-dataplane
kubectl get gtwpc -n tars-gateway

If using managed certificates, also verify certificate state:

gcloud certificate-manager certificates describe <certificate-name> \
--project <project-id> \
--format="yaml(name,managed.state,managed.domainStatus)"

On AWS, verify the egress Service has an NLB hostname and smoke-test it:

kubectl get service egress -n tars-dataplane \
-o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
curl -sk -o /dev/null -w 'HTTP %{http_code}\n' http://<nlb-hostname>:10080/v1/chat/completions

401 means the ingress is wired through to the tars-proxy filter (it is asking for an API key). 200 means the filter is not loaded; 502 means the load balancer health check is failing.

Troubleshooting

  • missing projectId: set --project-id or projectId in config when using prereq workflow
  • missing certificate map name: set --certificate-map-name or certificateMap.name in config
  • wait timeout: check Gateway events and cloud LB provisioning status
  • certificate still PROVISIONING: ensure DNS authorization record and final A record are correct
  • (AWS) EnvoyProxy "tars-egress-proxy" not found: run tare install first so the egress EnvoyProxy exists in tars-system, or pass --aws-envoyproxy <name> if it is named differently
  • (AWS) the egress Service stays ClusterIP after patching: confirm kubectl get envoyproxy tars-egress-proxy -n tars-system -o jsonpath='{.spec.provider.kubernetes.envoyService.type}' reads LoadBalancer, then check the envoy-gateway controller logs; Envoy Gateway must reconcile the EnvoyProxy into the Service
  • (AWS) NLB hostname never appears: run kubectl describe service egress -n tars-dataplane for events and check subnet discovery tags for the in-tree cloud provider