Skip to main content
Gå til innhold

Getting started with ArgoCD

Testing phase

ArgoCD on Platon is currently in a testing phase. If you want your team to be included, contact the Platon team on #platon on Slack and include the path to your GitLab project.

This guide walks you through deploying your first application to Platon using ArgoCD. By the end, your GitLab pipeline will render your Kubernetes manifests on every push, and ArgoCD will deploy them to the cluster.

Prerequisites​

Before you begin, you need:

How it works​

Platon's ArgoCD setup involves three repositories:

source repo (your project) deploy repo (argocd-apps/gl-proj-<id>)
────────────────────────── ──────────────────────────────────────
1. generate-manifests job ───────► 2. Downstream pipeline commits the
renders manifests/ with manifests into one directory per
envsubst environment:
prod/ staging/ rev-<branch>/
│
▼
app-config repo (Platon-managed) 3. ArgoCD deploys each directory to
──────────────────────────────── its own namespace:
Defines the ArgoCD AppProject, gl-proj-<id>-prod
Applications (prod, staging) and gl-proj-<id>-staging
ApplicationSet (review) gl-proj-<id>-review-<branch>

Understanding the three repositories​

Source repository (your responsibility) This is where your application code lives, along with your Kubernetes YAML templates in manifests/. The templates use placeholders that the pipeline replaces with real values.

Deploy repository (created when your project is bootstrapped) The repository that ArgoCD watches, at argocd-apps/gl-proj-<id>, where <id> is your GitLab project ID. Its contents are managed entirely by CI: your source repository's pipeline triggers the deploy repository's own pipeline, which commits the rendered manifests into a directory named after each environment. Do not edit it manually: the next deployment overwrites any changes made there.

App-config repository (managed by Platon) Holds the ArgoCD resources for every project. You have read-only access to it, so you can see how your project is configured, but changes are made by the Platon team:

  • AppProject (gl-proj-<id>): controls who can do what (RBAC) and which namespaces your applications may deploy to
  • Applications for production and staging: one fixed Application per environment
  • ApplicationSet for review environments: creates one Application per branch automatically

As a user, you work only with the source repository. The deploy repo is handled by your pipeline, and the app-config repo is managed by Platon.

Step 1 — Prepare your manifest templates​

Create a manifests/ directory in your repository with your Kubernetes YAML files. Both .yaml and .yml files are processed, and you can organise them into subdirectories:

my-app/
├── manifests/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── httpRoute.yaml
│ └── vaultStaticSecret.yaml # only needed if reading secrets from Vault
└── .gitlab-ci.yml

Use CI variables as placeholders for values that differ between environments or builds, for example $CI_COMMIT_SHA for the image tag. Resource names can stay the same in every environment: each environment, including each review branch, gets its own namespace, so deployments do not overwrite each other.

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: $REPLICAS
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

Leave out metadata.namespace. ArgoCD places every resource in the namespace for that environment.

Namespaces are created for you

Platon creates each environment's namespace, with default network policies, image pull credentials and resource policies already applied. Do not add Namespace resources to your manifests.

No Secrets in manifests

Do not put kind: Secret resources in your manifests. They would be committed in plain text to the deploy repository. The pipeline checks for them and fails the job if it finds one. Manage secrets through Vault instead, as described below.

For a complete working example with several apps, HTTPRoutes, network policies and a Vault secret, see hello-world-all-resources-gitops.

Accessing Vault secrets​

Every namespace Platon creates for you already contains a VaultAuth resource called vault-auth, which lets the namespace read your project's secrets in Vault. You only need to add a VaultStaticSecret saying which secret to fetch:

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: my-app-secret
spec:
vaultAuthRef: vault-auth
type: kv-v2
mount: secret
path: gitlab/<group>/<project>/<secret-name>
refreshAfter: 30s
destination:
name: my-app-secret
create: true

The Vault Secrets Operator reads the KV-v2 secret at path, creates a Kubernetes Secret named by destination.name, and refreshes it on the refreshAfter interval. Your pods can then use that Secret as usual.

The values you need to adjust:

  • path: where your secret is stored in Vault. Your project can read secrets under gitlab/<group>/<project>/ (see Vault structure).
  • destination.name: the name of the Kubernetes Secret to create

This also works for review environments: each new review namespace gets its own vault-auth automatically, so no manual Vault changes are needed. When the review environment is stopped, the namespace and its Secret are removed.

Step 2 — Configure your pipeline​

Include the Platon ArgoCD component in your .gitlab-ci.yml and define the two stages it uses. The component adds all the jobs for you:

include:
- component: $CI_SERVER_FQDN/platon/ci-components/argocd-deploy/deploy@main

stages:
- generate-manifests
- deploy

If you also build an image in the same pipeline, put your build stage before generate-manifests.

The component supports three environments:

EnvironmentRuns onEnabled by defaultArgoCD sync
reviewevery push to a branch other than the default branchyesautomatic
stagingevery push to the default branchnomanual
productionevery push to the default branchyesmanual

To turn environments on or off, use the component inputs. For example, to add staging:

include:
- component: $CI_SERVER_FQDN/platon/ci-components/argocd-deploy/deploy@main
inputs:
with-staging: true
InputDefaultDescription
with-reviewtrueReview environment per branch, plus a manual stop-review job
with-stagingfalseStaging environment from the default branch
with-productiontrueProduction environment from the default branch
templates-dirmanifestsDirectory containing your templates
Decide on your environments before bootstrapping

Bootstrapping reads these inputs from your .gitlab-ci.yml to decide which ArgoCD Applications to create. Commit the include with the environments you want before your project is bootstrapped. If you enable staging later, you can bootstrap the project again so that the staging Application is created.

To change a single job, declare a job with the same name. GitLab merges your keywords over the component's. For example, to require a manual click before deploying to production:

deploy-production:
when: manual

Review environments are stopped automatically after 14 days. You can also stop one earlier with the manual stop-review job, or by deleting the branch.

If you need a review environment that lasts longer, override the auto-stop setting in the same way:

deploy-review:
environment:
auto_stop_in: 30 days

Step 3 — Get your project bootstrapped​

Bootstrapping connects your project to ArgoCD. It:

  • creates your deploy repository, argocd-apps/gl-proj-<id>
  • sets the DEPLOY_REPOSITORY_PATH CI/CD variable on your source project, so the pipeline knows which repository to trigger
  • creates the AppProject, Applications and ApplicationSet for the environments enabled in your .gitlab-ci.yml
Testing phase

While ArgoCD on Platon is being tested, the Platon team bootstraps projects for you. Ask on #platon on Slack and include the path to your GitLab project.

After the testing phase, you will bootstrap your project yourself in PaaS Console: find your GitLab project, select the ArgoCD cluster and click the bootstrap button. You need the Maintainer or Owner role on the GitLab project to do this.

Step 4 — What the pipeline does​

When you push, the pipeline runs two stages:

Stage 1 — generate-manifests

The job runs envsubst on every .yaml and .yml file in manifests/, replacing each placeholder with the value of the variable it names. These can be built-in CI variables (such as $CI_COMMIT_SHA), variables defined in your .gitlab-ci.yml, or CI/CD variables from your project settings. The result is saved to manifests-generated/ as a pipeline artifact.

The job then checks the result and fails if:

  • no manifests were generated, because an empty environment would make ArgoCD delete everything in it
  • a file is not valid YAML after substitution
  • a file contains a kind: Secret

Stage 2 — deploy

The deploy job triggers the pipeline in your deploy repository, which replaces the environment's directory with the new manifests and commits them:

EnvironmentDirectory in deploy repoArgoCD ApplicationNamespace
productionprod/<project>-prodgl-proj-<id>-prod
stagingstaging/<project>-staginggl-proj-<id>-staging
reviewrev-<branch-slug>/<project>-review-<branch-slug>gl-proj-<id>-review-<branch-slug>

<project> is the last part of your GitLab project's URL, in lowercase. For gitlab.sikt.no/platon/example/hello-world it is hello-world. <id> is the gitlab project ID.

Step 5 — Verify the deployment​

Open the ArgoCD UI once the pipeline has finished. To find your applications, filter by the gitlab-project-name label or search for your project name. Click an application to see a live graph of all its Kubernetes resources. Each application and resource shows two statuses:

  • Sync status: Synced means everything in your manifests has been applied to the cluster. OutOfSync means the cluster differs from what is in the deploy repository, for example because a new version has not been synced yet.
  • Health status: Healthy (green heart) means the resources are running as expected, for example all pods of a Deployment are up and ready. Progressing means they are still starting, and Degraded means something is wrong, such as a pod that keeps crashing.

Your deployment succeeded when the application is both Synced and Healthy.

  • Review environments are synced automatically. The new review application appears within a few minutes of the pipeline finishing.
  • Production and staging are not synced automatically. After the pipeline finishes, the application shows OutOfSync. Click Sync → Synchronize to deploy. Only maintainers of the GitLab group can sync production (see Permissions).

You can also check from the command line:

kubectl get pods -n gl-proj-<id>-<environment>

Step 6 — Make a change​

The full loop looks like this:

  1. Edit your code or a manifest template in your source repository.
  2. Commit and push.
  3. GitLab CI renders the templates and commits them to the deploy repository.
  4. ArgoCD detects the new commit (it checks every 3 minutes by default, or click Refresh to check now).
  5. Review environments sync on their own. For staging and production, click Sync.

Next steps​