Argo CD With Gitlab CI - Part II

This is the second article in the series Argo CD with Gitlab CI. It can be read by its own, if you are only interested in Argo CD. Otherwise checkout the article Argo CD with Gitlab CI - Part I.

  • Argo CD with Gitlab CI - Part I

    In this article we will outline an example workflow how to integrate Gitlab CI with Argo CD to achieve a robust SDLC[^1] process that is suitable for enterprises as well as for your Homelab. This article will focus on the CI part with Gitlab.

  • Argo CD with Gitlab CI - Part II (this article)

    Goes into details how to deploy and use ArgoCD. It basically leverages the state and artifacts (docker images) generated and maintained via Gitlab.

In this article we will describe how setup Argo CD to use docker containers and Kubernetes configuration files (via kustomize) created and hosted by Gitlab and the related CI, as described in the first article.

Install and setup Argo CD

The installation of Argo CD follows the Getting Started guide from the official documentation with some minor modifications. Mainly we want to download locally the yaml file used to install Argo CD and create and ingress to be able to access the instance. In good old GitOps fashion we check everything in a dedicated git repository, such as gitlab.yourdomain/infrastructure/argocd.

The same way as for our application deployments we use kustomize.

Creating the necessary files

Make sure to change the Argo CD release version according to your needs and also to update ingress URL from argocd.yourdomain.com to your own domain or subdomain.

$ mkdir -p k8s/{base,overlays}
$ wget -O k8s/base/install-v2.4.15.yaml https://raw.githubusercontent.com/argoproj/argo-cd/v2.4.15/manifests/install.yaml
$ cat > k8s/base/kustomization.yaml << EOF
namespace: argocd
resources:
  # Downloaded from https://raw.githubusercontent.com/argoproj/argo-cd/v2.4.15/manifests/install.yaml
  - install-v2.4.15.yaml
EOF

$ mkdir -p k8s/overlays/production
$ cat > k8s/overlays/production/ingress.yaml << EOF
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: argocd-server
  namespace: argocd
spec:
  entryPoints:
    - websecure
  routes:
    - kind: Rule
      match: Host(\`argocd.yourdomain.com\`)
      priority: 10
      services:
        - name: argocd-server
          port: 80
    - kind: Rule
      match: Host(\`argocd.yourdomain.com\`) && Headers(\`Content-Type\`, \`application/grpc\`)
      priority: 11
      services:
        - name: argocd-server
          port: 80
          scheme: h2c
  tls:
    certResolver: default
EOF

$  cat > k8s/overlays/production/kustomization.yaml << EOF
bases:
  - ../../base

resources:
  - ingress.yaml

patchesJson6902:
- target:
    version: v1
    kind: ConfigMap
    name: argocd-cmd-params-cm
  patch: |-
    - op: replace
      path: /data
      value:
        server.insecure: "true"
EOF

# Check the newly create structure
$ tree .
.
└── k8s
    ├── base
    │   ├── install-v2.4.15.yaml
    │   └── kustomization.yaml
    └── overlays
        └── production
            ├── ingress.yaml
            └── kustomization.yaml

4 directories, 4 files

# Check if everything works by printing the final kube config to STDOUT
$ kustomize build k8s/overlays/production

Running the install

$ kubectl create namespace argocd
$ kubectl apply -k k8s/overlays/production

Deploying everything with Argo CD

Create a apps/production.yaml file as outlined below and point it to a repository under deployments/app-registry. This repositories needs to have a production directory hosting all the applications that you want to deploy. Deploy this file via kubectl apply -f production.yaml

---
apiVersion: v1
kind: Secret
metadata:
  name: apps-registry-git
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  insecure: 'true'
  url: https://gitlab.yourdomain.com/deployments/apps-registry.git
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: apps-registry
  namespace: argocd
spec:
  project: default
  source:
    repoURL: 'https://gitlab.yourdomain.com/deployments/apps-registry.git'
    path: production
    targetRevision: main
  destination:
    server: 'https://kubernetes.default.svc'
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

One example of an application in deployments/app-registry repository under the production directory. Content of the file lighting.yaml.

---
apiVersion: v1
kind: Secret
metadata:
  name: lighting-git
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  insecure: 'true'
  url: https://gitlab.yourdomain.com/deployments/lighting.git
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: lighting
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: 'https://gitlab.yourdomain.com/deployments/lighting.git'
    path: k8s/overlays/production
    targetRevision: main
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: smart-home
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

The git repository URL in this file is the same as the configuration repository that we updated in the previous article. Integrating our CI phase with the CD and on-going application monitoring phase.

What about credentials if the config repos are private?

Glad you asked. One of the reasons why we create a specific Gitlab group, deployments, where we have all our config repositories is to have group level credentials that are configured as follows. Make sure to change the the CHANGE_TO_ values to your credentials, create a new deploy token with the permissions read_repository via gitlab.yourdomain.com/groups/deployments/-/settings/repository

The file content of credentials/gitlab.yaml file that you should apply via kubectl apply -f credentials/gitlab.yaml.

---
apiVersion: v1
kind: Secret
metadata:
  name: gitlab-deployments-creds
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repo-creds
stringData:
  type: git
  url: https://gitlab.yourdomain.com/deployments
  username: CHANGE_TO_gitlab-deploy-token-username
  password: CHANGE_TO_gitlab-deploy-toke

Final directory and file state

If you followed this article and created the files as described you should end up with a directory structure as follows. Making the whole process reproducible and easy to update/change when necessary.

$ tree .
├── apps
│   └── production.yaml
├── credentials
│   ├── gitlab.yaml
├── k8s
│   ├── base
│   │   ├── install-v2.4.15.yaml
│   │   └── kustomization.yaml
│   └── overlays
│       └── production
│           ├── ingress.yaml
│           └── kustomization.yaml

If you need more credentials, e.g., for a different source code management platform or a different group just copy the credentials/gitlab.yaml file to a new one and make the appropriate changes. The same is true for the application registries under apps. Don’t forget to apply these new config files via kubectl apply.

The deplyoments/apps-registry git repository structure looks as follows. Adding new yaml files similar to lighting.yaml will trigger an automatic deployment via Argo CD.

$ tree .
.
├── production
└----── lighting.yaml
Author

Alex Oberhauser

Alex Oberhauser is a tech-entrepreneur, innovator and former C-level executive. He is currently working on user controlled identities and the empowerment of the end-users, with privacy and security as part of the value proposition, not as an afterthought.

Comments


You can use your Fediverse (e.g., Mastodon) account to reply to this post .

  

Reply to obale's post

With an account on the Fediverse, such as Mastodon, you can respond to this post. Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform.

Copy and paste this URL into the search field of your favorite Fediverse app or the web interface of your Mastodon server.