Edit

Share via


Tutorial: Deploy applications using GitOps with ArgoCD

This tutorial describes how to use GitOps in a Kubernetes cluster. GitOps with ArgoCD is enabled as a cluster extension in Azure Arc-enabled Kubernetes clusters or Azure Kubernetes Service (AKS) clusters. With GitOps, you can use your Git repository as the source of truth for cluster configuration and application deployment.

Important

GitOps with ArgoCD is currently in PREVIEW. See the Supplemental Terms of Use for Microsoft Azure Previews for legal terms that apply to Azure features that are in beta, preview, or otherwise not yet released into general availability. For production GitOps extension support, try the GitOps extension using Flux.

Tip

While the source in this tutorial is a Git repository, ArgoCD supports other common file sources such as Helm and Open Container Initiative (OCI) repositories.

Prerequisites

To deploy applications using GitOps, you need either an Azure Arc-enabled Kubernetes cluster or an AKS cluster:

Azure Arc-enabled Kubernetes clusters

Azure Kubernetes Service clusters

  • An MSI-based AKS cluster that's up and running.

    Important

    The AKS cluster needs to be created with Managed Service Identity (MSI), not Service Principal Name (SPN), for this extension to work. For new AKS clusters created with az aks create, the cluster is MSI-based by default. To convert SPN-based clusters to MSI, run az aks update -g $RESOURCE_GROUP -n $CLUSTER_NAME --enable-managed-identity. For more information, see Use a managed identity in AKS.

  • Read and write permissions on the Microsoft.ContainerService/managedClusters resource type.

Common to both cluster types

  • Read and write permissions on these resource types:

    • Microsoft.KubernetesConfiguration/extensions
  • Azure CLI version 2.15 or later. Install the Azure CLI or use the following commands to update to the latest version:

    az version
    az upgrade
    
  • The Kubernetes command-line client, kubectl. kubectl is already installed if you use Azure Cloud Shell.

    Install kubectl locally using the az aks install-cli command:

    az aks install-cli
    
  • Registration of the following Azure resource providers:

    az provider register --namespace Microsoft.Kubernetes
    az provider register --namespace Microsoft.ContainerService
    az provider register --namespace Microsoft.KubernetesConfiguration
    

    Registration is an asynchronous process and should finish within 10 minutes. To monitor the registration process, use the following command:

    az provider show -n Microsoft.KubernetesConfiguration -o table
    
    Namespace                          RegistrationPolicy    RegistrationState
    ---------------------------------  --------------------  -------------------
    Microsoft.KubernetesConfiguration  RegistrationRequired  Registered
    

Version and region support

GitOps is currently supported in all regions that Azure Arc-enabled Kubernetes supports. GitOps is currently supported in a subset of the regions that AKS supports. The GitOps service is adding new supported regions on a regular cadence.

Network requirements

The GitOps agents require outbound (egress) TCP to the repo source on either port 22 (SSH) or port 443 (HTTPS) to function. The agents also require access to the following outbound URLs:

Endpoint (DNS) Description
https://management.azure.com Required for the agent to communicate with the Kubernetes Configuration service.
https://<region>.dp.kubernetesconfiguration.azure.com Data plane endpoint for the agent to push status and fetch configuration information. Depends on <region> (the supported regions mentioned earlier).
https://login.microsoftonline.com Required to fetch and update Azure Resource Manager tokens.
https://mcr.microsoft.com Required to pull container images for controllers.

Enable CLI extensions

Install the latest k8s-configuration and k8s-extension CLI extension packages:

az extension add -n k8s-configuration
az extension add -n k8s-extension

To update these packages to the latest versions:

az extension update -n k8s-configuration
az extension update -n k8s-extension

To see a list of all installed Azure CLI extensions and their versions, use the following command:

az extension list -o table

Experimental   ExtensionType   Name                   Path                                                       Preview   Version
-------------  --------------  -----------------      -----------------------------------------------------      --------  --------
False          whl             connectedk8s           C:\Users\somename\.azure\cliextensions\connectedk8s         False     1.10.7
False          whl             k8s-configuration      C:\Users\somename\.azure\cliextensions\k8s-configuration    False     2.2.0
False          whl             k8s-extension          C:\Users\somename\.azure\cliextensions\k8s-extension        False     1.6.4

Create GitOps (ArgoCD) extension (simple installation)

The GitOps ArgoCD installation supports multi-tenancy in high availability (HA) mode and supports workload identity.

Important

The HA mode is the default configuration and requires three nodes in the cluster to be able to install. The command below adds --config deployWithHighAvailability=false to install the extension on a single node.

This command creates the simplest configuration installing the ArgoCD components to a new argocd namespace with cluster-wide access. Cluster-wide access enables ArgoCD app definitions to be detected in any namespace listed in the ArgoCD configmap configuration in the cluster. For example: namespace1,namespace2

az k8s-extension create --resource-group <resource-group> --cluster-names <cluster-name> \
--cluster-type managedClusters \
--name argocd \
--extension-type Microsoft.ArgoCD \
--auto-upgrade false \
--release-train preview \
--version 0.0.7-preview \
--config deployWithHightAvailability=false \
--config namespaceInstall=false \
–-config “config-maps.argocd-cmd-params-cm.data.application\.namespaces=namespace1,namespace2”

If you want to limit ArgoCD access to a specific namespace, use the --config namespaceInstall=true along with --target-namespace <namespace> parameters. This installation command creates a new <namespace> namespace and installs the ArgoCD components in the <namespace>. The installation command also enables the ability to install multiple instances of ArgoCD in the same cluster. ArgoCD application definitions in this configuration only function in the <namespace> namespace.

Create GitOps (ArgoCD) extension with workload identity

An alternative installation method recommended for production usage is workload identity. This method allows you to use Microsoft Entra ID identities to authenticate to Azure resources without needing to manage secrets or credentials in your Git repository. This installation utilizes workload identity authentication enabled in the 3.0.0-rc2 or later OSS version of ArgoCD.

Important

The HA mode is the default configuration and requires three nodes in the cluster to be able to install. Add --config deployWithHighAvailability=false to install the extension on a single node.

To create the extension with workload identity, first replace the following variables with your own values in this Bicep template:

var clusterName = '<aks-or-arc-cluster-name>'

var workloadIdentityClientId = 'replace-me##-##-###-###'
var ssoWorkloadIdentityClientId = 'replace-me##-##-###-###'

var url = 'https://<public-ip-for-argocd-ui>/auth/callback'
var oidcConfig = '''
name: Azure
issuer: https://login.microsoftonline.com/<your-tenant-id>/v2.0
clientID: <same-value-as-ssoWorkloadIdentityClientId-above>
azure:
  useWorkloadIdentity: true
requestedIDTokenClaims:
  groups:
    essential: true
requestedScopes:
  - openid
  - profile
  - email
'''

var defaultPolicy = 'role:readonly'
var policy = '''
p, role:org-admin, applications, *, */*, allow
p, role:org-admin, clusters, get, *, allow
p, role:org-admin, repositories, get, *, allow
p, role:org-admin, repositories, create, *, allow
p, role:org-admin, repositories, update, *, allow
p, role:org-admin, repositories, delete, *, allow
g, replace-me##-argocd-ui-Microsoft Entra-group-admin-id, role:org-admin
'''

resource cluster 'Microsoft.ContainerService/managedClusters@2024-10-01' existing = {
  name: clusterName
}

resource extension 'Microsoft.KubernetesConfiguration/extensions@2023-05-01' = {
  name: 'argocd'
  scope: cluster
  properties: {
    extensionType: 'Microsoft.ArgoCD'
    autoUpgradeMinorVersion: false
    releaseTrain: 'preview'
    version: '0.0.7-preview'
    configurationSettings: {
      'workloadIdentity.enable': 'true'
      'workloadIdentity.clientId': workloadIdentityClientId
      'workloadIdentity.Microsoft EntraSSOClientId': ssoWorkloadIdentityClientId
      'config-maps.argocd-cm.data.oidc\\.config': oidcConfig
      'config-maps.argocd-cm.data.url': url
      'config-maps.argocd-rbac-cm.data.policy\\.default': defaultPolicy
      'config-maps.argocd-rbac-cm.data.policy\\.csv': policy
      'config-maps.argocd-cmd-params-cm.data.application\\.namespaces': 'default, argocd'
    }
  }
}

The Bicep template can be created using this command:

az deployment group create --resource-group <resource-group> --template-file <bicep-file>

Parameters

clusterName is the name of the AKS or Arc-enabled Kubernetes cluster.

workloadIdentityClientId and ssoWorkloadIdentityClientId are the client IDs of the managed identity desired to be used for workload identity. The ssoWorkloadIdentityClientId is used for the authentication for the ArgoCD UI and the workloadIdentityClientId is used for the workload identity for the ArgoCD components. Visit Microsoft Entra ID App Registration Auth using OIDC for additional information on general setup and configuration of the ssoWorkloadIdentityClientId.

url is the public IP of the ArgoCD UI. There's no public IP or domain name unless the cluster already has a customer provided ingress controller. If so, the ingress rule needs to be added to the ArgoCD UI after deployment.

oidcConfig - replace <your-tenant-id> with the tenant ID of your Microsoft Entra ID. Replace <same-value-as-ssoWorkloadIdentityClientId-above> with the same value as ssoWorkloadIdentityClientId.

policy variable is the argocd-rbac-cm configmap settings of ArgoCD. g, replace-me##-argocd-ui-entra-group-admin-id is the Microsoft Entra group ID that gives admin access to the ArgoCD UI. The Microsoft Entra group ID can be found in the Azure portal under Microsoft Entra ID > Groups > your-group-name > Properties. You can use the Microsoft Entra user ID instead of a Microsoft Entra group ID. The Microsoft Entra user ID can be found in the Azure portal under Microsoft Entra ID > Users > your-user-name > Properties.

Create workload identity credentials

To set up new workload identity credentials, follow these steps:

  1. Retrieve the OIDC issuer URL for your AKS cluster or Arc-enabled Kubernetes cluster.

  2. Create a managed identity and note its client ID and tenant ID.

  3. Establish a federated identity credential for your AKS cluster or Arc-enabled Kubernetes cluster. For example:

    # For source-controller
    az identity federated-credential create --name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} --identity-name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --issuer "${OIDC_ISSUER}" --subject system:serviceaccount:"argocd":"source-controller" --audience api://AzureADTokenExchange
    
  4. Be sure to provide proper permissions for workload identity for the resource that you want source-controller or image-reflector controller to pull. For example, if using Azure Container Registry, ensure either Container Registry Repository Reader (for ABAC-enabled registries) or AcrPull (for non-ABAC registries) has been applied.

Connect to private ACR registries or ACR repositories using workload identity

To utilize the private ACR registry or ACR repositories, follow the instructions in the official ArgoCD documentation for connecting to private ACR registries. The Label the Pods, Create Federated Identity Credential, and Add annotation to Service Account steps in that guide were completed by the extension with the Bicep deployment and can be skipped.

Access the ArgoCD UI

If there's no existing ingress controller for the AKS cluster, then the ArgoCD UI can be exposed directly using a LoadBalancer service. The following command will expose the ArgoCD UI on port 80 and 443.

kubectl -n argocd expose service argocd-server --type LoadBalancer --name argocd-server-lb --port 80 --target-port 8080

Deploy ArgoCD application

Now that the ArgoCD extension is installed, you can deploy an application using the ArgoCD UI or CLI. The following example simply uses kubectl apply to deploy AKS store inside an ArgoCD application to the default ArgoCD project in the argocd namespace.

kubectl apply -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: aks-store-demo
  namespace: argocd
spec:
  project: default
  source:    
      repoURL: https://github.com/Azure-Samples/aks-store-demo.git
      targetRevision: HEAD
      path: kustomize/overlays/dev
  syncPolicy:
      automated: {}
  destination:
      namespace: argocd
      server: https://kubernetes.default.svc
EOF

The AKS store demo application was installed into the pets namespace. See the application webpage by following these instructions. Be sure to visit the IP address using http and not https.

Update extension configuration

ArgoCD configmaps can be updated after installation and other extension configuration settings using the following command:

az k8s-extension update --resource-group <resource-group> --cluster-name <cluster-name> --cluster-type <cluster-type> --name Microsoft.ArgoCD –-config "config-maps.argocd-cm.data.url='https://<public-ip-for-argocd-ui>/auth/callback'”

It's important to update the ArgoCD configmap through the extension, so the settings don't get overwritten. Applying the bicep template is an alternate method to the az cli to update the configuration.

Delete the extension

Use the following commands to delete the extension.

az k8s-extension delete -g <resource-group> -c <cluster-name> -n argocd -t managedClusters --yes

Next steps