Application deployment

The deployment of application composition projects follows the GitOps framework to automate the deployment onto different deployment targets. The main components of the framework are the Git repository (to store the application configuration), the (https://cloud.redhat.com/learn/topics/gitops/? extIdCarryOver=true&sc_cid=701f2000001OH7EAAW)(to manage the cluster configurations) and the external secret controller (to resolve external secrets into kubernetes secrets).

Deployment steps

  • Create application: Once the user chooses to create an application composition project, a Git repository is created for the application to maintain the application configuration for different deployment targets as part of the composite application. The configuration of each deployment target is maintained in a separate branch with branch name as deployment target name.

  • Selecting deployment target: Deployment is managed individually for each deployment target. Choosing deployment target results in:

    1. Creating a branch in the Git repository of the application to manage all the configuration for this specific deployment target. A kustomization file is created in that branch which maintains the resources to be deployed.

        apiVersion: kustomize.config.k8s.io/v1beta1
        kind: Kustomization
        resources:
          - {{resource1}}.yaml
          - {{resource2}}.yaml
        patches:
          - target:
              version: v1alpha1
              kind: Application
              labelSelector: app={{applicationAcronym}}
            patch: |-
              - op: replace
                path: /spec/source/helm/parameters/0/value
                value: {{deploymentTargetHostName}}
          - target:
              version: v1alpha1
              kind: Application
              labelSelector: app={applicationAcronym}
            patch: |-
              - op: replace
                path: /spec/source/helm/parameters/4/value
                value: 'false'
          - target:
              version: v1alpha1
              kind: Application
              labelSelector: app=abatest
            patch: |-
              - op: add
                path: /metadata/finalizers
                value: ['resources-finalizer.argocd.argoproj.io/foreground']
          - target:
              version: v1alpha1
              kind: Application
              labelSelector: app={{applicationAcronym}}
            patch: |-
              - op: add
                path: /spec/syncPolicy
                value:
                  automated:
                    selfHeal: true
                    prune: true
      • resource.yaml: These are the yaml files which contain the configuration of a specific component or binding which is part of the application.

      • applicationAcronym: Acronym for the application

      • deploymentTargetHostName: The target hostname of the deployment target.

      • patches: Patches are used to add or override fields in resource configuration.

    Creating (https://argo-cd.readthedocs. io/en/stable/operator-manual/declarative-setup/#applications) in the cluster to manage the state of the application in the kubernetes cluster. This application will always sync with the Git repository to look for any change in the state of the application and apply that state to the cluster.

  • Deploy components: After the deployment target is selected, you can add components to the deployment target. Each component is treated as individual resource of the application and has a corresponding component yaml file in the Git repository which contains the configuration of the component:

    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
    name: {{componentDeploymentName}}
    namespace: argocd
    labels:
        app: {{applicationAcronym}}
        type: component
    annotations:
        description: {{application component description}}
    spec:
      destination:
          namespace: {{deploymentTarget}
          server: 'https://kubernetes.default.svc'
      project: default
      source:
        repoURL: {{helmRepoUrl}}
        chart: {{componentChartName}}
        targetRevision: {{componentChartVersion}}
        helm:
          parameters:
            - name: environment.host
            value: host
            - name: label.application
            value: {{application acronym}}
            - name: image.registryPath
            value: {{deploymnt target path}}
            - name: deployment.applicationAcronym
            value: {{application acronym}}
            - name: feature.istio
            value: {{istioFlag}}
          values: '{{customConfig}}'
    • componentDeploymentName: A unique application deployment resource name. Created with combination of {{applicationAcronym}}-{{componentName}}-{{targetDeployment}}

    • applicationAcronym: Acronym for the application

    • deploymentTarget: Chosen deployment target

    • helmRepoUrl: URL of the helm oci repository where the component's helm chart is available

    • componentChartName: Name of the helm chart of the component, same as component name

    • componentChartVersion: Version of the helm chart to use

    • customConfig: Stringified version of custom configuration.

    Once the component is added and committed to Git, ArgoCD application created in previous step will read this component yaml file and deploy the helm chart available in source spec of the file onto the target namespace of the kubernetes cluster. Also, argoCd will apply any custom configurations specified by the user in custom configuration.

  • Deploy bindings: Each API binding and topic binding is treated as a single resource for deployment to the cluster. Since bindings might contain some sensitive data, in order to protect binding data being stored directly in the Git, binding resources are created in form of external secrets where only a path for the actual binding data is stored in the Git repository. When an API or topic binding is required for a component this has to be configured by user. Once the user commits these changes to the deployment target, an external secret resource yaml for each binding is created in Git:

    apiVersion: k5.config/v1
    kind: K5ExternalSecret
    metadata:
      name: {{externalSecretName}}
      namespace: {{deploymentTarget}}
    spec:
      backendType: vault
      data:
        - key: {{secretDataPath}}
          name: binding
      vaultMountPoint: kubernetes
      vaultRole: external-secrets-role

    ArgoCD application reads these external secret resource files from Git, and adds the corresponding external secrets to the kubernetes cluster. Once the external secrets are available in the cluster, the external secret controller will use these external secrets to fetch the secret data from the external Provider (vault). The external secret controller then uses this data to create a kubernetes secret which can be accessed by pods of the application.

Similar to adding components and bindings, if the user removes any resource from the application and commits the changes to the Git, Argocd application with sync up with the Git repository and clean up the removed resources from cluster.