Skip to content

Bootstraping

Starting from not having a Project Syn environment to having one is, of course, a little bit of a chicken and egg situation. In this section we begin almost from scratch, meaning; we have a functioning clusters, able to start pods, that we then use to run Lieutenant (Operator & API), which then manages itself.

Prerequisites

A cluster with:

  • Networking
  • Ingress
  • Cert-Manager (recommended)

Install Lieutenant Operator & API

Info

For this purpose I crated a Helm chart, later we use Project Syn to manage this component.

helm repo add tegridy https://charts.tegridy.io/stable

We need to customize the following parameters, create a lieutenant.yaml file:

operator:
  env:
    DEFAULT_DELETION_POLICY: Archive
    DEFAULT_GLOBAL_GIT_REPO_URL: ssh://git@gitlab.com/your-org/commodore-defaults.git
    LIEUTENANT_DELETE_PROTECTION: "true"
    SKIP_VAULT_SETUP: "true"

api:
  env:
    DEFAULT_API_SECRET_REF_NAME: gitlab-com
    LIEUTENANT_INSTANCE: lieutenant

  ingress:
    annotations:
      cert-manager.io/issuer: lieutenant-issuer
    url: syn.your-org.com
    tls: true

Now install Lieutenant Operator & API on your cluster:

helm install --namespace infra-lieutenant --create-namespace -f ./lieutenant.yaml lieutenant tegridy/lieutenant

The only thing missing are the credentials for our GitLab repositories:

export GITLAB_ENDPOINT="gitlab.com"
export GITLAB_TOKEN=xxx

kubectl -n infra-lieutenant create secret generic gitlab-com \
  --from-literal=endpoint="https://${GITLAB_ENDPOINT}" \
  --from-literal=hostKeys="$(ssh-keyscan $GITLAB_ENDPOINT)" \
  --from-literal=token="$GITLAB_TOKEN"

Create tenant and cluster

With the Lieutenant Operator & API running, we can now create a tenant and a cluster. We can directly create the Kubernetes objects.

Create the tenant object:

cat <<EOF | kubectl -n infra-lieutenant apply -f -
  apiVersion: syn.tools/v1alpha1
  kind: Tenant
  metadata:
    name: tegridy-io
  spec:
    displayName: Some name was ok
    gitRepoTemplate:
      path: tegridy-io/syn               # path to your group
      repoName: tenant-tegridy-io        # name of tenant-repository
      deletionPolicy: Delete
      apiSecretRef:
        name: gitlab-com
    clusterTemplate:
      gitRepoTemplate:
        path: tegridy-io/syn             # path to catalog group
        repoName: cluster-{{ .Name }}    # template for cluster repo name
        deletionPolicy: Delete
        apiSecretRef:
          name: gitlab-com
EOF

Create the cluster object:

cat <<EOF | kubectl -n infra-lieutenant apply -f -
apiVersion: syn.tools/v1alpha1
kind: Cluster
metadata:
  name: hilarious-tabby
spec:
  displayName: Some cluster
  tenantRef:
    name: tegridy-io                     # tenant of this cluster
  tokenLifeTime: 4h
  facts:                                 # facts about the cluster
    distribution: k3s
    cloud: hetzner
    region: eu-central
EOF

Bootstrap Steward on cluster

To interact with the API you'll need a token:

export COMMODORE_TOKEN=$(k -n infra-lieutenant get secret lieutenant-api-user -ojsonpath={.data.token} | base64 -d)

Download Steward installation manifest:

export INSTALL_STEWARD=$(curl -sL -H "Authorization: Bearer $COMMODORE_TOKEN" "https://syn.your-org.com/clusters/hilarious-tabby" | jq -r ".installURL")
curl -sL $INSTALL_STEWARD > ./steward.json

Info

This is not strictly necessary, but if you wan't to install Steward into a different namespace do the following:

export NEW_NAMESPACE="efk-system"

# Replace in namespaced resources
cat <<< $(jq --arg ns "$NEW_NAMESPACE" '(.items[] | select(.metadata.namespace != null)) .metadata.namespace |=  $ns' ./steward.json) > ./steward.json

# Replace namespace name
cat <<< $(jq --arg ns "$NEW_NAMESPACE" '(.items[] | select(.kind == "Namespace")).metadata.name |= $ns' ./steward.json) > ./steward.json

# Replace rolebinding subject namespace
cat <<< $(jq --arg ns "$NEW_NAMESPACE" '(.items[] | select(.kind == "ClusterRoleBinding")).subjects[].namespace |= $ns' ./steward.json) > ./steward.json

Apply Steward manifests to the cluster:

kubectl apply -f ./steward.json

Your cluster has now Steward installed and will deploy a minimal ArgoCD:

kubectl -n syn get po
NAME                                  READY   STATUS    RESTARTS   AGE
argocd-application-controller-0       1/1     Running   0          13s
argocd-redis-7b5dc774d9-krnfq         1/1     Running   0          13s
argocd-repo-server-6649bbfbdd-mklnc   2/2     Running   0          13s
argocd-server-6454794b94-m2g2q        1/1     Running   0          13s
steward-5d759f7fb6-kkls6              1/1     Running   0          61s

Create minimal cluster config

Now lets have a look at the associated Git repositories.

Global Defaults

The global defaults repository we have to create ourselves. You can create your own hierarchy, but for the beginning a bare minimum is all we need.

Define your hierarchy in the commodore.yaml file:

classes:
- global.components
- ${cluster:tenant}.${cluster:name}

Create the components.yaml file, where we define the components used:

parameters:
  components:
    argocd:
      url: https://github.com/projectsyn/component-argocd.git
      version: v5.4.0

    lieutenant:
      url: https://github.com/projectsyn/component-lieutenant.git
      version: v2.11.3

    steward:
      url: https://github.com/projectsyn/component-steward.git
      version: v3.5.2

Tenant Repository

The tenant repository was creted by the Lieutenant Operator and should alredy be populated with the cluster config.

Edit the c-your-cluster.yaml file to contain the following:

classes:
  - tegridy-io.common

applications:
  - lieutenant

parameters:
  lieutenant:
    namespace: infra-lieutenant

    operator:
      default_global_git_repo: ssh://git@gitlab.com/tegridy-io/syn/commodore-defaults.git
      env:
        LIEUTENANT_CREATE_SERVICEACCOUNT_TOKEN_SECRET: true
        SKIP_VAULT_SETUP: "true"

    api:
      ingress:
        host: syn.your-org.com
        annotations:
          cert-manager.io/cluster-issuer: letsencrypt-prod

    auth_delegation:
      lieutenant-sa:
        apiGroup: rbac.authorization.k8s.io
        kind: Group
        name: system:serviceaccounts
        namespace: infra-lieutenant

    tenant_template:
      # GitRepo template for cluster repo
      clusterTemplate:
        gitRepoTemplate:
          apiSecretRef:
            name: gitlab-com
          path: tegridy-io/syn
          repoName: cluster-{{ .Name }}
      # GitRepo template for tenant repo
      gitRepoTemplate:
        apiSecretRef:
          name: gitlab-com
        path: tegridy-io/syn
        repoName: tenant-{{ .Name }}

Info

Ideally we now also wan't to manage Steward and ArgoCD with Commodore, but for this we will need a way to manage secrets. Later we will add Vault to be able to do that.

Compile cluster catalog

We can now use Commodore to compile the cluster catalog for the first time:

commodore catalog compile c-your-cluster --api-token $COMMODORE_TOKEN --push -i

...
Updating catalog repository...
 > Changes:
     Added file manifests/apps/lieutenant.yaml
     ...
 > Should the push be done? [y/N]: y
 > Commiting changes...
 > Pushing catalog to remote...
Catalog compiled! 🎉

Clean up

Since we bootstrapped lieutenant from the Helm chart we might have some cleaning up to do.

Use the ArgoCD dashboard to look whats troubling it:

argocd admin dashboard --namespace syn

You probably wan't to delete the deployments:

kubectl -n infra-lieutenant delete deploy lieutenant-api lieutenant-operator