convoy docs
Search

Deploy from Git

Deploy plain manifests, a kustomization and a Helm chart with values layers from a GitRepository.

This guide deploys the podinfo application from its Git repository to the cluster where convoy runs. It shows the three content types that convoy renders from a GitRepository: plain manifests, a kustomization and a Helm chart. The Helm part also reads a values file from a second Git repository. The source is an endpoint only. Each Release selects a branch, a tag or a commit.

Before you start#

  • convoy runs in the cluster.
  • kubectl and the kubectl convoy plugin are on your PATH.
  • You can create convoy objects in the default namespace. All examples use this namespace.

Steps#

1. Create the target Cluster#

  1. Save this manifest as cluster-auth-in-cluster.yaml:

    clusters/cluster-auth-in-cluster.yaml
    apiVersion: core.convoy.kumodo.io/v1alpha1
       kind: Cluster
       metadata:
         name: dev-local
         namespace: default
       spec:
         connectionMode: inCluster
         metadata:
           type: kind
           role: managed
       
  2. Apply the manifest:

    sh
    kubectl apply -f cluster-auth-in-cluster.yaml
  3. Wait until the Cluster is ready:

    sh
    kubectl wait --for=condition=Ready clusters.core.convoy.kumodo.io/dev-local -n default --timeout=2m

2. Create the GitRepository#

  1. Save this manifest as gitrepository-podinfo.yaml:

    sources/gitrepository-podinfo.yaml
    apiVersion: source.convoy.kumodo.io/v1alpha1
       kind: GitRepository
       metadata:
         name: podinfo
         namespace: default
       spec:
         auth:
           type: none
         interval: 1m0s
         minSyncInterval: 30s
         tls:
           insecureSkipVerify: true
         url: https://github.com/stefanprodan/podinfo.git
       
  2. Apply the manifest:

    sh
    kubectl apply -f gitrepository-podinfo.yaml

A Release does not wait for the Ready condition of the source. It fetches the commit directly. A branch can move, so convoy fetches a branch again at each reconcile.

3. Deploy plain manifests#

  1. Save this manifest as release-gitrepository-manifests-in-cluster.yaml:

    releases/release-gitrepository-manifests-in-cluster.yaml
    apiVersion: core.convoy.kumodo.io/v1alpha1
       kind: Release
       metadata:
         name: podinfo-in-cluster
         namespace: default
       spec:
         clusterRef:
           name: dev-local
         source:
           type: gitRepository
           gitRepository:
             name: podinfo
             namespace: default
             ref:
               branch: master
         content:
           type: manifests
           manifests:
             paths:
               - kustomize/deployment.yaml
               - kustomize/service.yaml
         syncPolicy:
           automatic: true
           prune:
             orphaned: false
             includeCRDs: false
             includeNamespaces: false
           interval: 1m
       
  2. Apply the manifest:

    sh
    kubectl apply -f release-gitrepository-manifests-in-cluster.yaml
  3. Wait until convoy applies the render:

    sh
    kubectl wait --for=condition=Applied release/podinfo-in-cluster -n default --timeout=5m

Each entry of spec.content.manifests.paths is a file or a directory in the repository. For a directory, convoy reads all .yaml and .yml files below it, in name order. A path without a YAML file stops the render.

The two podinfo files have no metadata.namespace. convoy applies them to the default namespace. The targetNamespace field of manifests content does not change this.

4. Deploy a kustomization#

  1. Create the target namespace:

    sh
    kubectl create namespace podinfo-kustomize
  2. Save this manifest as release-gitrepository-kustomize-in-cluster.yaml:

    releases/release-gitrepository-kustomize-in-cluster.yaml
    apiVersion: core.convoy.kumodo.io/v1alpha1
       kind: Release
       metadata:
         name: podinfo-kustomize-in-cluster
         namespace: default
       spec:
         clusterRef:
           name: dev-local
         source:
           type: gitRepository
           gitRepository:
             name: podinfo
             namespace: default
             ref:
               branch: master
         content:
           type: kustomize
           kustomize:
             path: kustomize
             targetNamespace: podinfo-kustomize
         syncPolicy:
           automatic: true
           prune:
             orphaned: false
             includeCRDs: false
             includeNamespaces: false
           interval: 1m
       
  3. Apply the manifest:

    sh
    kubectl apply -f release-gitrepository-kustomize-in-cluster.yaml
  4. Wait until convoy applies the render:

    sh
    kubectl wait --for=condition=Applied release/podinfo-kustomize-in-cluster -n default --timeout=5m

convoy runs kustomize in the controller. It does not call the kustomize binary. spec.content.kustomize.path must contain a kustomization.yaml, kustomization.yml or Kustomization file.

targetNamespace sets the namespace of each namespaced object of the build. It replaces a namespace that the kustomization sets. convoy does not create the namespace. If the namespace does not exist, the pre-apply dry run fails, and the Applied reason is Unappliable.

5. Deploy a Helm chart with values from Git#

  1. Save this manifest as gitrepository-podinfo-values.yaml:

    sources/gitrepository-podinfo-values.yaml
    apiVersion: source.convoy.kumodo.io/v1alpha1
       kind: GitRepository
       metadata:
         name: podinfo-values
         namespace: default
       spec:
         auth:
           type: none
         interval: 1m0s
         minSyncInterval: 30s
         tls:
           insecureSkipVerify: true
         url: https://github.com/BROngineer/podinfo-values.git
       
  2. Save this manifest as release-gitrepository-helm-values-from-git.yaml:

    guides/release-gitrepository-helm-values-from-git.yaml
    apiVersion: core.convoy.kumodo.io/v1alpha1
       kind: Release
       metadata:
         name: podinfo-git-values
         namespace: default
       spec:
         clusterRef:
           name: dev-local
         source:
           type: gitRepository
           gitRepository:
             name: podinfo
             namespace: default
             ref:
               branch: master
         content:
           type: helm
           helm:
             path: charts/podinfo
             releaseName: podinfo-git-values
             releaseNamespace: default
             dependencyMode: vendored
             values:
               - type: gitRepository
                 gitRepository:
                   name: podinfo-values
                   namespace: default
                   ref:
                     branch: main
                   paths:
                     - podinfo/values.yaml
               - type: inline
                 inline:
                   replicaCount: 2
         syncPolicy:
           automatic: true
           prune:
             orphaned: true
             includeCRDs: false
             includeNamespaces: false
           interval: 1m
       
  3. Apply the two manifests:

    sh
    kubectl apply -f gitrepository-podinfo-values.yaml -f release-gitrepository-helm-values-from-git.yaml
  4. Wait until convoy applies the render:

    sh
    kubectl wait --for=condition=Applied release/podinfo-git-values -n default --timeout=5m

The chart comes from charts/podinfo in the podinfo repository. For a GitRepository source, spec.content.helm.path selects the chart directory.

spec.content.helm.values has two layers:

  1. A gitRepository layer. convoy fetches podinfo-values at the branch main and reads podinfo/values.yaml. This file sets replicaCount: 3. This layer has its own ref, independent of the chart source.
  2. An inline layer that sets replicaCount: 2.

convoy merges the layers in list order. A later layer wins. Maps merge, and all other values, lists too, replace the earlier value. Helm then merges the result over the values.yaml of the chart. If a file in paths does not exist, the Applied reason is ValuesNotReady. See Rendering.

All references must be in the namespace of the Release. This includes the gitRepository values layer.

Check the result#

  1. Show the Releases:

    sh
    kubectl get releases -n default

    The header line is NAME CONTENT SOURCE CLUSTER STATE APPLIED INSYNC HEALTHY LIFECYCLE AGE. For each Release of this guide, make sure that APPLIED is True.

  2. Show the objects of the kustomize render:

    sh
    kubectl convoy release preview podinfo-kustomize-in-cluster -n default

    Make sure that each namespaced object has namespace: podinfo-kustomize.

  3. Show the merged Helm values in the render:

    sh
    kubectl convoy release preview podinfo-git-values -n default

    Make sure that the Deployment has replicas: 2. The inline layer replaced the value from the Git layer.

  4. Compare the live objects with the render:

    sh
    kubectl convoy release diff podinfo-in-cluster -n default

If APPLIED is not True, read the reason of the Applied condition with kubectl describe release <name> -n default.

Clean up#

  1. Delete the Releases:

    sh
    kubectl delete release podinfo-in-cluster podinfo-kustomize-in-cluster podinfo-git-values -n default
  2. Delete the sources:

    sh
    kubectl delete -f gitrepository-podinfo.yaml -f gitrepository-podinfo-values.yaml
  3. Delete the namespace:

    sh
    kubectl delete namespace podinfo-kustomize
  4. Delete the Cluster, if no other Release uses it:

    sh
    kubectl delete -f cluster-auth-in-cluster.yaml

Delete the Releases first. The Release finalizer deletes the objects of each Release from the target cluster. It needs the Cluster for this. See Deletion.

Next steps#

In the code

convoy v0.9.0