CNE Azure Ready: Bootstrap Configuration Reference
One config.json file configures a Cloud Native Experience (CNE) deployment on Azure: the AKS cluster, the platform stack, the GitOps connection, and the bootstrap execution options. Required keys are marked in the Default column.
Create config.json in your bootstrap working directory, as Bootstrapping Your Initial Environment describes.
The bootstrap merges your config.json over the config.json.defaults file bundled in the bootstrap package. That file holds only the artifacts object, so your file can omit artifacts. Every other key comes from your file or from the Terraform variable defaults listed below. Values you place in the GitOps repository, such as liferay.yaml and infrastructure.yaml, are covered in the Helm Values Reference. No config.json key controls backups. Set them per environment in the GitOps repository.
Top-Level Keys
These keys sit at the root of config.json. A missing key stops the run with The configuration JSON file must contain a key named "<key>".
| Name | Type | Default | Description |
|---|---|---|---|
deployment_name | String | (Required) | Names the deployment. It is also the name of the resource group the stacks create and the prefix of the resources they name, such as <deployment_name>-aks, <deployment_name>-vnet, <deployment_name>-nat, and <deployment_name>-nsg. |
region | String | (Required) | Sets the Azure region for the deployment, such as eastus2. |
subscription_id | String | (Required) | Sets the ID of the Azure subscription that holds the deployment. |
tenant_id | String | (Required) | Sets the ID of the Microsoft Entra tenant for the subscription. |
The bootstrap passes deployment_name and region to every Terraform stack, and they override any value for the same variable under terraform.
Options
Define these in a root-level options object to control how the bootstrap runs Terraform.
| Name | Type | Default | Description |
|---|---|---|---|
provider | String | None | Sets the infrastructure provider that the launcher runs. Valid values are aws, azure, and gcp. Use azure. |
version | String | latest | Sets the bootstrap release to download, such as 0.3.0. latest selects the most recent release. |
auto_approve | Boolean | false | When true, adds -auto-approve to every Terraform apply and destroy. With false, Terraform asks you to approve each apply and destroy. Set it to true for runs that need no input. |
parallelism | Number | None | Passes the value to Terraform as -parallelism=<value>. When omitted, the bootstrap passes no -parallelism flag. |
Remote Terraform State
The optional tfstate object stores Terraform state in an Azure storage account. Omit it to keep state on the local machine. When the object is present, all three keys are required, and setup creates the resource group, the storage account, and the container if they do not exist.
| Name | Type | Default | Description |
|---|---|---|---|
container_name | String | (Required) | Names the blob container that holds the state files. |
resource_group_name | String | (Required) | Names the resource group for the storage account. |
storage_account_name | String | (Required) | Names the storage account for the state. Azure requires 3 to 24 characters, using lowercase letters and numbers only, so hyphens are not allowed. |
Database (setup)
Set the database engine in the setup object:
| Name | Type | Default | Description |
|---|---|---|---|
setup.database.engine | String | (Required) | Sets the database engine for Liferay DXP. Set it to postgresql. The bootstrap checks the value against the liferay-azure-infrastructure-provider chart’s schema before it creates anything. |
Shared Terraform Variables
The terraform object holds the Terraform variables for the two stacks: terraform.aks for the AKS cluster and terraform.platform for the platform. Variables in terraform.common apply to both. For each stack, the bootstrap merges terraform.common with the stack’s own object, and the stack’s object wins where both set a variable.
AKS Cluster Variables
Set these in terraform.aks.
| Name | Type | Default | Description |
|---|---|---|---|
machine_type | String | "Standard_D8s_v3" | Sets the VM size of the system node pool. |
system_node_count | Number | 2 | Sets the number of nodes in the system node pool. |
vpc_cidr | String | "10.0.0.0/16" | Sets the address space of the virtual network. The cluster subnet is cidrsubnet(vpc_cidr, 4, 0), which is 10.0.0.0/20 for the default. |
pod_cidr | String | "10.244.0.0/16" | Sets the address range for pods in the Azure CNI overlay network. |
service_cidr | String | "10.245.0.0/16" | Sets the address range for Kubernetes services. The cluster DNS service address is fixed at 10.245.0.10 and is not derived from this value. |
private_cluster | Boolean | false | When true, the cluster API server has no public endpoint. |
api_authorized_ip_ranges | List(String) | [] | Lists the CIDR ranges allowed to reach the API server. The setting applies only when private_cluster is false and the list is not empty. |
container_registries | Map(Object) | {} | Lists the container registries the cluster pulls from. Each entry is an object with an id, the registry’s resource ID. The kubelet identity gets AcrPull on each. |
host_encryption_enabled | Boolean | false | When true, turns on encryption at host for the system node pool. |
You cannot change these cluster settings through config.json:
- The Kubernetes version follows the
stableautomatic upgrade channel, and node images upgrade automatically. - Networking uses Azure CNI overlay with Cilium.
- Outbound traffic leaves through a NAT gateway.
- Node Auto Provisioning is on.
- Workload identity and the OIDC issuer are on.
- The network security group admits inbound TCP traffic on ports 80 and 443 from the internet for the Envoy gateway.
Platform Variables
Set these in terraform.platform.
| Name | Type | Default | Description |
|---|---|---|---|
cluster_secret_store | Object | (Required) | Sets the backing store for the cluster’s External Secrets. Set exactly one of key_vault or provider_hcl. See Cluster Secret Store. |
keda_config | Object | {} | Configures KEDA autoscaling. See KEDA and Observability. |
observability_config | Object | {} | Configures Azure Monitor observability. See KEDA and Observability. |
argocd_admin_login_enabled | Boolean | true | Sets whether the Argo CD admin account can log in. |
argocd_external_access_config | Object | null | Configures external access to Argo CD with hostname (String), sso_enabled (Boolean, default false), and tls_enabled (Boolean, default false). It sets Argo CD’s URL to http://<hostname>, or https://<hostname> when tls_enabled is true. See Configuring Argo CD Domain and TLS. |
argocd_helm_chart_version | String | "10.1.3" | Sets the version of the Argo CD Helm chart. |
Cluster Secret Store
Set these in terraform.platform.cluster_secret_store:
| Name | Type | Default | Description |
|---|---|---|---|
key_vault | Object | None | Names an existing Azure key vault with name and resource_group_name. The platform grants the External Secrets identity Key Vault Secrets User on the vault and creates the cluster secret store <deployment_name>-secret-store. The vault must use the Azure RBAC permission model. |
provider_hcl | Any | None | Sets a custom External Secrets provider in place of Key Vault. The value is the External Secrets ClusterSecretStore spec.provider object, such as {"vault": {"server": "https://vault.example.com:8200", ...}}. With it, the bootstrap skips the Key Vault role assignment, and you configure the provider’s authentication. |
If neither or both are set, Terraform stops with The variable "cluster_secret_store" must set either "key_vault" (an existing Azure key vault for backing the cluster secret store) or "provider_hcl" (a custom External Secrets provider).
A vault on the access policy permission model stops the run with The key vault <name> uses the access policy permission model, but the Liferay platform grants vault access through Azure RBAC roles, so the External Secrets operator would be denied access.
KEDA and Observability
Set these in terraform.platform:
| Name | Type | Default | Description |
|---|---|---|---|
keda_config.enabled | Boolean | false | Provisions KEDA for autoscaling. KEDA is provisioned only when observability_config.enabled is true. |
keda_config.namespace | String | "keda-system" | Sets the namespace of the KEDA operator. |
keda_config.service_account_name | String | "keda-operator" | Sets the service account of the KEDA operator. |
observability_config.enabled | Boolean | false | Creates an Azure Monitor workspace <deployment_name>-amw, a data collection endpoint and rule, and an identity for the observability stack. This is the object’s only key. |
When these resources exist, the bootstrap turns on the KEDA and observability applications itself, so no platformComponents flag is needed. For the procedures, see Configuring Autoscaling and Monitoring With Grafana.
Platform Components Values
Values in platformComponents.values configure the liferay-platform-components chart. They merge over the values the bootstrap generates, so a value you set replaces the bootstrap’s, and a list you set replaces the whole list. The one exception is database.engine, which the bootstrap sets from setup.database.engine after merging your values.
GitOps Repository
Set these in platformComponents.values.gitops.repository.
| Name | Type | Default | Description |
|---|---|---|---|
url | String | "" | Sets the URL of your GitOps repository. Nothing validates the value, but every ApplicationSet the platform creates reads it. |
revision | String | "HEAD" | Sets the Git revision to track, such as a branch name. |
method | String | "https" | Sets the authentication method: https, ssh, or github_app. With registerCredentials on, another value fails with Unsupported git repository auth method: <method>. |
credentialsSecretName | String | "liferay-credentials-gitops" | Names the secret in the cluster secret store that holds the repository credentials. |
usernameProperty | String | "git_machine_user_id" | Names the property in the credentials secret that holds the Git user name (HTTPS). |
tokenProperty | String | "git_access_token" | Names the property in the credentials secret that holds the access token (HTTPS). |
sshPrivateKeyProperty | String | "git_ssh_private_key" | Names the property in the credentials secret that holds the SSH private key (SSH). |
githubAppIdProperty | String | "github_app_id" | Names the property in the credentials secret that holds the GitHub App ID (GitHub App). |
githubAppInstallationIdProperty | String | "github_app_installation_id" | Names the property in the credentials secret that holds the GitHub App installation ID (GitHub App). |
githubAppPrivateKeyProperty | String | "github_app_private_key" | Names the property in the credentials secret that holds the GitHub App private key (GitHub App). |
registerCredentials | Boolean | true | Registers the credentials with Argo CD. |
internalSecretName | String | "git-repo-gitops-credentials" | Names the Kubernetes secret that holds the credentials for Argo CD. |
platformComponents.values.gitops.infrastructureRepository takes the same keys for a separate infrastructure repository. Its url and revision default to empty and fall back to the values in repository. Its internalSecretName defaults to "git-repo-infrastructure-credentials".
platformComponents.values.gitops.layout sets the folder and file names the platform reads from the repository, such as environments (default "liferay/projects/*/environments/*") and liferayValuesFilename (default "liferay.yaml"). For what goes in those files, see the Helm Values Reference.
Gateways, SSO, and Access Control
Set these in platformComponents.values in config.json. For the procedures, see CNE Azure Ready: Configuring Argo CD Domain and TLS.
| Name | Type | Default | Description |
|---|---|---|---|
argocd.gateway.enabled | Boolean | false | Exposes Argo CD through an Envoy gateway. |
argocd.gateway.hostname | String | "" | Sets the host name for the Argo CD gateway. It is required when the gateway is enabled. |
argocd.gateway.tls.externalSecretKey | String | "" | Names the secret in the cluster secret store that holds the gateway’s TLS certificate. |
argocd.gateway.envoyProxy.* | Object | replicas: 2 | Sets the Envoy proxy’s replicas, podAnnotations, and serviceAnnotations. |
argocd.gateway.clientTrafficPolicySpec | Object | {} | Sets the Envoy client traffic policy for the gateway. |
argocd.sso.enabled | Boolean | false | Turns on single sign-on for Argo CD. |
argocd.sso.credentialsSecretKey | String | "" | Names the secret in the cluster secret store that holds the SSO credentials. |
argoWorkflows.gateway.* | Object | See argocd.gateway.* | Sets the same gateway keys for Argo Workflows. |
accessControl.enabled | Boolean | false | Restricts both gateways to the ranges in allowedCIDRs. |
accessControl.allowedCIDRs | List(String) | [] | Lists the CIDR ranges allowed to reach the gateways. They are required when access control is enabled. |
Operator Applications
platformComponents.values.operatorApplications.<name>.enabled turns each operator application on or off, and targetRevision pins its chart version.
| Operator | Enabled by Default | Chart Version |
|---|---|---|
argoWorkflows | Yes | 2.0.3 |
crossplane | Yes | 2.1.3 |
dxpOperator | Yes | 0.2.0 |
eckOperator | Yes | 3.2.0 |
envoyGateway | Yes | 1.6.3 |
externalSecrets | Yes | 2.9.0 |
keda | No | 2.19.0 |
The bootstrap enables keda itself when keda_config provisions KEDA, and sets observability.enabled when observability_config provisions the Azure Monitor workspace. Set those features in terraform.platform rather than here.
Values the Bootstrap Fills
The bootstrap sets these values from the Terraform outputs and the artifacts. Leave them unset:
clusterSecretStoredatabase.engine, set fromsetup.database.enginedeploymentContextinfrastructure.parameters, which sets the Elasticsearch storage class tomanaged-csi-premium-v2liferay.parametersandobservability.parameters, whenobservability_configprovisions the Azure Monitor workspacenetworkPolicy.apiServerSourcesoperatorApplications.dxpOperator.values.imageoperatorApplications.externalSecrets.values.serviceAccount.annotations, which carries the External Secrets identity’s client ID- The
repoURLandtargetRevisionofinfrastructure,infrastructureProvider,liferay,observability, andoperatorApplications.dxpOperator
Artifacts
The artifacts object sets where the bootstrap gets each chart and image. The defaults bundled with the bootstrap point to the 0.3.0 set. Override an entry only to use another registry.
| Name | Default Version | Default Registry |
|---|---|---|
artifacts.charts.liferay-azure | 0.3.0 | us-central1-docker.pkg.dev/external-assets-prd/liferay-helm-chart |
artifacts.charts.liferay-azure-infrastructure-provider | 0.3.0 | us-central1-docker.pkg.dev/external-assets-prd/liferay-helm-chart |
artifacts.charts.liferay-platform | 0.3.0 | us-central1-docker.pkg.dev/external-assets-prd/liferay-helm-chart |
artifacts.charts.liferay-platform-components | 0.3.0 | us-central1-docker.pkg.dev/external-assets-prd/liferay-helm-chart |
artifacts.charts.liferay-infrastructure | 0.2.0 | us-central1-docker.pkg.dev/external-assets-prd/liferay-helm-chart |
artifacts.charts.liferay-dxp-operator | 0.2.0 | us-central1-docker.pkg.dev/external-assets-prd/liferay-helm-chart |
artifacts.charts.observability | 2.0.0 | us-central1-docker.pkg.dev/external-assets-prd/liferay-helm-chart |
artifacts.images.liferay-dxp-operator | 0.2.0 | us-central1-docker.pkg.dev/external-assets-prd/liferay-cloud-native |
Each entry has a registry and a version key. Because your file merges over the defaults, omitting an entry keeps its default.
Example
This config.json file is the one CNE Azure Ready: Bootstrapping Your Initial Environment uses:
{
"deployment_name": "clarity",
"options": {
"auto_approve": false,
"parallelism": 10,
"provider": "azure",
"version": "0.3.0"
},
"platformComponents": {
"values": {
"gitops": {
"repository": {
"url": "https://github.com/clarity-vision-solutions/liferay-gitops.git"
}
}
}
},
"region": "eastus2",
"setup": {
"database": {
"engine": "postgresql"
}
},
"subscription_id": "your-azure-subscription-id",
"tenant_id": "your-azure-tenant-id",
"terraform": {
"platform": {
"cluster_secret_store": {
"key_vault": {
"name": "your-key-vault-name",
"resource_group_name": "your-key-vault-resource-group"
}
},
"keda_config": {
"enabled": true
},
"observability_config": {
"enabled": true
}
}
},
"tfstate": {
"container_name": "tfstate",
"resource_group_name": "clarity-tfstate",
"storage_account_name": "claritytfstate"
}
}