Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

How to easily deploy OpenShift on Azure via GitOps

March 17, 2023
Ignacio Lago Pablo Castelo
Related topics:
ContainersGitOpsKubernetes
Related products:
Microsoft Azure Red Hat OpenShiftRed Hat Advanced Cluster Management for KubernetesRed Hat OpenShiftRed Hat OpenShift Container Platform

    Deploying Red Hat OpenShift in Microsoft Azure utilizing OpenShift GitOps makes it not only easier but enables you to achieve faster time to market, better collaboration, more efficient workflows, and ensures access to the cloud's scalability, flexibility, and reliability.

    In this article, we are going to follow the same process from our previous article but use a GitOps approach for this.

    [ Learning path: Getting started with Microsoft Azure Red Hat OpenShift (ARO) ] 

    Step 1: Setting up the credentials for Azure in GitOps

    First of all, we have to fork the repository, so we can make changes to it since we are going to use the integration from the previous article. In between Red Hat Advanced Cluster Management for Kubernetes and Argo CD to deploy the changes (Argo CD reads a Git repository). Now we can take a look at the repo:

    tree -L 2
    .
    ├── README.md
    ├── bootstrap
    │   ├── argocd
    │   └── deploy
    └── resources
        ├── 01-acm-operator
        ├── 02-azure-credentials
        └── 03-azure-cluster
    
    7 directories, 1 file

    We need to edit the folders for the 02-azure-credentials and 03-azure-cluster.

    Let us take a look at what is inside the folders. The ./resources/02-azure-credentials are shown in the following snippet:

    tree -L 2./resources/02-azure-credentials 
    ./resources/02-azure-credentials
    ├── 00-azure-credentials-namespace copy.yaml
    ├── 01-azure-credentials-secret.yaml
    └── kustomization.yaml
    
    0 directories, 3 files

    Here we need to edit the file 01-azure-credentials-secret.yaml. Let us take a look at that file and what we have to replace. In this case, the baseDomainResourceGroupName¹, PullSecret², the baseDomain³, the SSH private⁵⁴ and public⁵ keys:

    cat resources/02-azure-credentials/01-azure-credentials-secret.yaml 
    ---
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
      annotations:
        argocd.argoproj.io/sync-wave: "1"
      name: azure-credentials
      namespace: azure-credentials
      labels:
        cluster.open-cluster-management.io/type: azr
        cluster.open-cluster-management.io/credentials: ""
    stringData:
      # 1 resource group created for the DNS to be used as base in the installation
    baseDomainResourceGroupName: openenv-jrh4l
      cloudName: AzurePublicCloud
     # 2 ClientId + ClientSecret + TenantId + SubscriptionId in json format
      osServicePrincipal.json: '{"clientId":"client_id_here","clientSecret":"client_secret_here","tenantId":"tenant_id_here","subscriptionId":"subscription_id_here"}'
      # 3 base DNS to be used as base in the installation
       baseDomain: jrh4l.azure.something.io
      # Your pull secret for pulling the images
      pullSecret: >
        {pull_secret_here}
      # Your Private Key for accessing the machines
    4 ssh-privatekey: |
        -----BEGIN OPENSSH PRIVATE KEY-----
                private_key_here
        -----END OPENSSH PRIVATE KEY-----
      # Your Public Key for accessing the machines
    5 ssh-publickey: >
        ssh-rsa
        public_key_here
      httpProxy: ""
      httpsProxy: ""
      noProxy: ""
      additionalTrustBundle: ""

    Step 2: Install the cluster in Azure via GitOps

    Let us take a look at what is inside the folders. The ./resources/02-azure-credentials are shown in the following snippet:

    tree -L 2./resources/03-azure-cluster    
    ./resources/03-azure-cluster
    ├── 00-azure-cluster-namespace.yaml
    ├── 01-azure-managedclusterset copy.yaml
    ├── 02-azure-cluster.yaml
    └── kustomization.yaml
    
    0 directories, 4 files

    Here we need to edit the file 02-azure-cluster.yaml. Let us take a look at that file and what we have to replace. In this case, the Cluster Name, Cluster Namespace, the baseDomain, the baseDomainResourceGroupName, Base64 encoding of the pull secret, install-config.yaml in base64 encoding, ssh-private key, osServicePrincipal.json:

    cat resources/03-azure-cluster/02-azure-cluster.yaml 
    ---
    apiVersion: v1
    kind: Namespace
    metadata:
      name: cluster01
    ---
    apiVersion: hive.openshift.io/v1
    kind: ClusterDeployment
    metadata:
    # 1 Cluster name in this case is cluster01
        name: 'cluster01'
    # 2 Cluster namespace in this case is cluster01
       namespace: 'cluster01'
      labels:
        cloud: 'Azure'
        region: 'westeurope'
        vendor: OpenShift
        cluster.open-cluster-management.io/clusterset: 'azure-clusters'
    spec:
    # 3 base DNS to be used as base in the installation
       baseDomain: jrh4l.azure.something.io
      clusterName: 'cluster01'
      controlPlaneConfig:
        servingCertificates: {}
      installAttemptsLimit: 1
      installed: false
      platform:
        azure:
    # 4 resource group created for the DNS to be used in the installation
           baseDomainResourceGroupName: openenv-jrh4l
          credentialsSecretRef:
            name: cluster01-azure-creds
          region: westeurope
          cloudName: AzurePublicCloud
      provisioning:
        installConfigSecretRef:
          name: cluster01-install-config
        sshPrivateKeySecretRef:
          name: cluster01-ssh-private-key
        imageSetRef:
           #quay.io/openshift-release-dev/ocp-release:4.10.53-x86_64
          name: img4.10.53-x86-64-appsub
      pullSecretRef:
        name: cluster01-pull-secret
    ---
    apiVersion: cluster.open-cluster-management.io/v1
    kind: ManagedCluster
    metadata:
      labels:
        cloud: Azure
        region: westeurope
        name: 'cluster01'
        vendor: OpenShift
        cluster.open-cluster-management.io/clusterset: 'azure-clusters'
      name: 'cluster01'
    spec:
      hubAcceptsClient: true
    ---
    apiVersion: hive.openshift.io/v1
    kind: MachinePool
    metadata:
      name: cluster01-worker
      namespace: 'cluster01'
    spec:
      clusterDeploymentRef:
        name: 'cluster01'
      name: worker
      platform:
        azure:
          osDisk:
            diskSizeGB: 128
          type: Standard_D2s_v3
          zones:
          - "1"
          - "2"
          - "3"
      replicas: 3
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: cluster01-pull-secret
      namespace: 'cluster01'
    data:
    # 5 Base64 encoding of the pull secret
       .dockerconfigjson: >-
        pull_secret_in_base64
    type: kubernetes.io/dockerconfigjson
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: cluster01-install-config
      namespace: 'cluster01'
    type: Opaque
    data:
    # 6 Base64 encoding of install-config yaml
       install-config.yaml: YXBpVmVyc2lvbjogdjENCm1ldGFkYXRhOg0KICBuYW1lOiAnY2x1c3RlcjAxJw0KIyBiYXNlIEROUyB0byBiZSB1c2VkIGFzIGJhc2UgaW4gdGhlIGluc3RhbGxhdGlvbg0KYmFzZURvbWFpbjoganJoNGwuYXp1cmUuc29tZXRoaW5nLmlvDQpjb250cm9sUGxhbmU6DQogIGFyY2hpdGVjdHVyZTogYW1kNjQNCiAgaHlwZXJ0aHJlYWRpbmc6IEVuYWJsZWQNCiAgbmFtZTogbWFzdGVyDQogIHJlcGxpY2FzOiAzDQogIHBsYXRmb3JtOg0KICAgIGF6dXJlOg0KICAgICAgb3NEaXNrOg0KICAgICAgICBkaXNrU2l6ZUdCOiAxMjgNCiAgICAgIHR5cGU6ICBTdGFuZGFyZF9ENHNfdjMNCmNvbXB1dGU6DQotIGh5cGVydGhyZWFkaW5nOiBFbmFibGVkDQogIGFyY2hpdGVjdHVyZTogYW1kNjQNCiAgbmFtZTogJ3dvcmtlcicNCiAgcmVwbGljYXM6IDMNCiAgcGxhdGZvcm06DQogICAgYXp1cmU6DQogICAgICB0eXBlOiAgU3RhbmRhcmRfRDJzX3YzDQogICAgICBvc0Rpc2s6DQogICAgICAgIGRpc2tTaXplR0I6IDEyOA0KICAgICAgem9uZXM6DQogICAgICAtICIxIg0KICAgICAgLSAiMiINCiAgICAgIC0gIjMiDQpuZXR3b3JraW5nOg0KICBuZXR3b3JrVHlwZTogT1ZOS3ViZXJuZXRlcw0KICBjbHVzdGVyTmV0d29yazoNCiAgLSBjaWRyOiAxMC4xMjguMC4wLzE0DQogICAgaG9zdFByZWZpeDogMjMNCiAgbWFjaGluZU5ldHdvcms6DQogIC0gY2lkcjogMTAuMC4wLjAvMTYNCiAgc2VydmljZU5ldHdvcms6DQogIC0gMTcyLjMwLjAuMC8xNg0KcGxhdGZvcm06DQogIGF6dXJlOg0KICAgICMgcmVzb3VyY2UgZ3JvdXAgY3JlYXRlZCBmb3IgdGhlIEROUyB0byBiZSB1c2VkIGFzIGJhc2UgaW4gdGhlIGluc3RhbGxhdGlvbg0KICAgIGJhc2VEb21haW5SZXNvdXJjZUdyb3VwTmFtZTogb3BlbmVudi1qcmg0bA0KICAgIGNsb3VkTmFtZTogQXp1cmVQdWJsaWNDbG91ZA0KICAgIHJlZ2lvbjogd2VzdGV1cm9wZQ0KcHVsbFNlY3JldDogIiIgIyBza2lwLCBoaXZlIHdpbGwgaW5qZWN0IGJhc2VkIG9uIGl0J3Mgc2VjcmV0cw0Kc3NoS2V5OiB8LQ0KICAgIHNzaC1yc2ENCiAgICBwdWJsaWNfa2V5X2hlcmUNCg==
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: cluster01-ssh-private-key
      namespace: 'cluster01'
    stringData:
    # 7  we have to put our private ssh key in base64 here
        ssh-privatekey: >-
        private_ssh_key_in_base64
    type: Opaque
    ---
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
      name: cluster01-azure-creds
      namespace: 'cluster01'
    stringData:
    # 8 we have to put the azure credentials in base 64 here 
       osServicePrincipal.json: >-
        azure_credentials_in_base64
    ---
    apiVersion: agent.open-cluster-management.io/v1
    kind: KlusterletAddonConfig
    metadata:
      name: 'cluster01'
      namespace: 'cluster01'
    spec:
      clusterName: 'cluster01'
      clusterNamespace: 'cluster01'
      clusterLabels:
        cloud: Azure
        vendor: OpenShift
      applicationManager:
        enabled: true
      policyController:
        enabled: true
      searchCollector:
        enabled: true
      certPolicyController:
        enabled: true
      iamPolicyController:
        enabled: true

    Before deploying it, we need to change the application sets so it points to our newly forked repository. Take a look at the deploy folder in the following snippets:

    tree -L 2 bootstrap/deploy 
    bootstrap/deploy
    ├── 00-applicationset-acm
    │   ├── 00-acm-appproject.yaml
    │   ├── 01-acm-appset.yaml
    │   └── kustomization.yaml
    ├── 01-applicationset-azure-credentials
    │   ├── 00-azure-credentials-appproject.yaml
    │   ├── 01-azure-credentials-appset.yaml
    │   └── kustomization.yaml
    └── 02-applicationset-azure-cluster
        ├── 01-azure-cluster-appset.yaml
        └── kustomization.yaml
    
    3 directories, 8 files
    cat bootstrap/deploy/01-applicationset-azure-credentials/01-azure-credentials-appset.yaml
    
    ---
    apiVersion: argoproj.io/v1alpha1
    kind: ApplicationSet
    metadata:
      name: azure-credentials
      namespace: openshift-gitops
    spec:
      generators:
      - clusters: {} 
      template:
        metadata:
          name: azure-credentials-{{name}}
        spec:
          project: azure
          syncPolicy:
            automated:
              prune: true
              selfHeal: true
          source:
    # we have to replace this with our forked repository
            repoURL: https://github.com/ignaciolago/acm-ocp-azure.git
            targetRevision: main
            path: resources/02-azure-credentials
          destination:
            server: https://kubernetes.default.svc
    
    
    cat bootstrap/deploy/02-applicationset-azure-cluster/01-azure-cluster-appset.yaml 
    
    
    ---
    apiVersion: argoproj.io/v1alpha1
    kind: ApplicationSet
    metadata:
      name: azure-cluster
      namespace: openshift-gitops
    spec:
      generators:
      - clusters: {} 
      template:
        metadata:
          name: azure-cluster-{{name}}
        spec:
          project: azure
          syncPolicy:
            automated:
              prune: true
              selfHeal: true
          source:
    # we have to replace this with our forked repository
            repoURL: https://github.com/ignaciolago/acm-ocp-azure.git
            targetRevision: main
            path: resources/03-azure-cluster
          destination:
            server: https://kubernetes.default.svc
    
    

    Now we are ready to deploy. Run the following commands:

    oc apply -k bootstrap/deploy/01-applicationset-azure-credentials
    oc apply -k bootstrap/deploy/02-applicationset-azure-cluster

    We can track the process in the web GUI or get the logs from the pod in the namespace cluster01.

    oc get pods -n cluster01
    
    oc get logs pod-name -n cluster01

    Quick and easy deployment OpenShift on Azure

    Congrats on deploying OpenShift on Azure in only a few steps! In these two articles, we have shown two easy ways to deploy OpenShift on Azure: GUI and GitOps. Comment below if you have questions. As always, we welcome your feedback.

    Last updated: October 26, 2023

    Related Posts

    • Create an Azure Red Hat OpenShift cluster in less than 5 minutes

    • OpenShift support for GitOps processes

    • Why should developers care about GitOps?

    • Improved support information for RHEL on Azure: sosreport plugin updated

    • Introduction to the Red Hat OpenShift deployment extension for Microsoft Azure DevOps

    Recent Posts

    • MCP servers vs. skills: Choosing the right context for your AI

    • How to route external and local LLMs with Models-as-a-Service

    • Protect data offloaded to GPU-accelerated environments with OpenShift sandboxed containers

    • Case study: Measuring energy efficiency on the x64 platform

    • How to prevent AI inference stack silent failures

    What’s up next?

    Gitops Cookbook e-book tile card

    GitOps has become a standard in deploying applications to Kubernetes, and many companies are adopting the methodology for their DevOps and cloud-native strategy. Get useful recipes and examples for successful hands-on applications development and deployment with GitOps in this free O'Reilly e-book.

    Download the GitOps Cookbook
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Chat Support

    Please log in with your Red Hat account to access chat support.