# ArgoCD Up & Running
# Chapter 1: Introduction
## Why ArgoCD
- Rollback and Disaster Recovery
- Configuration Drift
- Unifying Application Definitions
## GitOps
- Declarative
- Versioned and immutable
- Pulled automatically
- Continuously reconciled
## Argo Ecosystem
- Argo Workflows: workflow engine for AI/ML, CI
- ArgoCD
- Argo Rollouts: deployment strategies
- Argo Events: event bus
# Chapter 2: Installing Argo CD
## Argo CD Architecture
### Overview

**Repository Server**
Stores cache of remote source. It generates resources based on params (repo type, location, path, ...). Custom plugins are executed in this component since they influence the generation of K8s manifests.
**API server**
gRPC/REST server, RBAC enforcement, app manage, status, management operations.
### Argo CD Key Patterns
Stateless & declerative, even the configuration for ArgoCD itself.
Extensibility: multiple VCS sources, Helm/Kustomize integration.
## Installing ArgoCD
### Installation Types

### Deploying ArgoCD
- Raw manifests
- Helm
- Operator (in work)
# Chapter 3: Interacting with ArgoCD
## More on UI

## CLI
More features, settings, like change admin password
## Additional Methods
- Restful API under `/swagger-ui`
- Configmap & secret settings


# Chapter 4: Managing Applications
## Application Sources
- Two sources of truth: Git and Helm
- Using `sources` with ignore `source` field
## Destinations
- Default (in-cluster) or remote clusters (hub-and-spoke)
## Tools
- Helm and Kustomize
## Deleting Applications
### Finalizers
By default, deleting a finalizer will cascadely delete all of its resources (foreground), ArgoCD does this by adding the finalizer.
```
metadata:
finalizers:
# The default behaviour is foreground cascading deletion
- resources-finalizer.argocd.argoproj.io
# Alternatively, you can use background cascading deletion
# - resources-finalizer.argocd.argoproj.io/background
```
# Chapter 5: Synchronizing Applications
## Managing How Applications Are Synced
- By default, no auto sync.
- Enable auto sync:
```
spec:
syncPolicy:
automated: {}
```
## Sync Options
- via `.spec.syncPolicy.syncOptions` or resources's annotations
### Application-Level Options
Some options:
- `Validate`: k8s API validation for manifests (default true)
- `ApplyOutOfSyncOnly`: too many manifests case (true by default)
- `PrunePropagationPolicy`: how to handle GC - prune/delete (default foreground)
- `PruneLast`: final part of sync operation (default true)
- `Replace`: delete and recreate, useful if `last-applied-config` too large (default false)
- `ServerSideApply`: often used with `Validate=false` (default true)
- `FailOnSharedResource`: failed with shared resources (default true)
- `RespectIgnoreDifferences`: default true
### Resource-Level Options
Define the annotation `argocd.argoproj.io/sync-options`
## Sync Order and Hooks
### Hooks
- PreSync, Sync, PostSync, SyncFail, PostDelete: dependent on previous phase status
- use annotation `argocd.argoprj.io/hook` to choose the phase (default is Sync)
- `hook-delete-policy`: delete resources of hooks: HookSucceeded, HookFailed, BeforeHookCreation. Hooks with name with only be run onced.
### Sync Waves
- Order by annotation `argocd.argoprj.io/sync-wave`
- Can be combined with sync phase to order resources
## Comparing Options
`argocd.argoproj.io/compare-options: IgnoreExtraneous` to ignore resource (outofsync), but the Application is healthy
## Managing Resource Differences
### Application-Level Diffing

### System-Level Diffing
In `argocd-cm`

# Chapter 6: Authentication and Authorization
## Managing Users
### Admin user
Initial user, password stored in secret
### Local Users
Defined in `argocd-cm` CM with format `accounts.<username>`

### SSO
- Dex OIDC: separate pod, Github, Gitlab, Google, Microsoft
- Direct OIDC: Google, Keycloak
## RBAC
### Argo CD RBAC Basics
Defined in `argocd-rbac-cm`
Two definition structures for RBAC

Grant a role to a user/group or role
```
g, <user/group/role>, <role>
```
### RBAC Defaults
Is defined in `argocd-cm-rbac`
```
kubectl patch -n argocd cm argocd-cm-rbac --type='merge' \
-p='{"data": {"policy.default": "role:<name_of_role>"}}'
```
### Anonymous Access
Use the `users.anonymous.enabled` in `argocd-cm`. Users are granted the level of access by RBAC Defaults
# Chapter 7: Cluster Management
## Cluster Architecture

### How Clusters Are Defined
ArgoCD sees clusters as just Kubernetes API endpoints (both local and remote clusters)

## Adding Remote Clusters
From argocd CLI, pass the Kubeconfig, Argo then create a SA in kube-system with appropriate RBAC permissions for managing the remote cluster
## Deploying Applications to Multi Clusters
Application is 1:1 with cluster -> how to deploy applications to multi clusters?
### App-of-Apps Pattern
Recovery from failure, sync phases, sync waves for apps

### Using Helm
Now it's recommended to use ApplicationSets

### ApplicationSets
A CRD for templating ArgoCD Applications
There are a list of `generators` (method to generate information for Application).
- List (k/v)
- Cluster
- Git
- Matrix
- Merge
- SCM Provider
- Pull Request (preview env)
- Cluster Decision Resource
- Plugin (self made)
Sync phases and sync waves are not fully supported -> use App-of-Apps
# Chapter 8: Multi-Tenancy
## Projects
`AppProject` CRD, used to group multiple Applications
## Resource Management
The first matching rule takes precedence, so deny rules must be before allow rules.
Can restrict these properties:
- source repos
- destinations
- namespace-scoped objects
- cluster-scoped objects
Can enable RBAC for applications:

# Chapter 9: Security
## Securing ArgoCD
Enabling TLS for ArgoCD server and configure Nginx Ingress controller to passthrough SSL traffic
## Configuring TLS Certificates
Add certificates for repositories
## Protected Repositories
Using HTTPS or SSH-based credentials to access repositories
Credential templates allows configuring credentials to access multiple repositories with URL prefix
## Enforcing Signature Verification
Currently only enabled for Git source, import the GPG public keys (that are used to sign commits) into ArgoCD. Only signed commits can be synced
## Application Sync Impersonation
By default, the SA ArgoCD used for sync applications is the one that interacts with control plane and has very high permission
From ArgoCD 2.14, admins can specify a specific service account to sync applications
### Enable sync impersonation
Setting `application.sync.impersonation.enabled: "true"` in `argocd-cm`
### Define SA to sync applications
Define in the `AppProjects`

Should not use a catchall namespace for service account, it should fail if the namespace is invalid
# Chapter 10: Applications at Scale
## Application Drawbacks
Sync waves are good for application's manifests order, but still lacks of multi applications coordination
Use the following strategies:
- Eventual consistency
- App-of-Apps with sync waves
- ApplicationSet Progressive Sync
## Consideration and Best Practices
- Configure probes (liveness / readiness)
- ArgoCD health custom checks (using Lua)
## Eventual Consistency
Using retry to retry multiple times sync actions would help achieve eventual healthy.
Set `argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true` also would help and should be used
## App-of-Apps with sync waves
To better use this feature, `probes` and `application health check` are needed
## ApplicationSets
Create multiple Applications and deploy to multiple clusters at once
### Progressive Sync
No order or dependencies by default. Progressive Sync help deploys Applications in order
Some things to note:
- Autosync is disabled by default for all Applications
- Alpha feature, need to be explicitly enabled
- If Application pending more than 30 secs -> ApplicationSet controller marks as healthy
Still need to setup probes and application health checks

# Chapter 11: Extending ArgoCD
## Config Management Plugins
Alternative config management tools (to Helm, Kustomize, Jsonnet) are executed in repo server:
- ConfigManagementPlugin manifest: how and when plugin is used
- Tooling to execute
Preferered method: package assets as sidecar to repo server
### The ConfigManagementPlugin manifest
`init`: preparation steps
`generate`: primary function, execution of scripts or binaries -> generate YAML or JSON as requirement
`discover`: set of rules that determines whether the Application is applicable for
execution
```
discover:
fileName: "Chart.yaml" # execute plugin if the file exists
```
Example manifest:
```
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
name: kustomize-helm
spec:
generate:
command: ["/bin/sh", "-c"]
args: ["kustomize build --enable-helm"]
```
### Registering the Plugin
Add a sidecar with plugin manifest mounted in the plugind directory with the repo server
### Customization execution
Use env vars or parameters to customize the plugin execution at Application-level
## UI Customization
### Banner Notifications
Setting the `ui.bannercontent`, `ui.bannerposition`, `ui.bannerpermanent` in `argocd-cm` ConfigMap

### Custom Styles
Changing logo, background of ArgoCD depends on the environment.
Using `argocd-styles-cm` ConfigMap to achieve the CSS customization.
### UI Extensions
UI extensions written in React, mounted as a configmap inside the argocd-server pods
Example: metrics tab, rollout tab,...
# Chapter 12: Integrating CI with ArgoCD
## Reconciliation Response Time
By default, ArgoCD uses reconciliation (loop) to pull changes from VCS, but it also allows webhooks
### Modifying Reconciliation
Default: 180 seconds, `timeout.reconciliation` in `argocd-cm`
### Setting Up Webhooks
Setting the webhook secret: `webhook.gogs.secret`
Configure the webhook push from VCS repository
## CI/CD Integration via Tekton
### Building a Tekton pipeline
Using Tekton PipelineRun -> Tekton Pipeline -> Tekton Task to run tasks within cluster that interacts with the ArgoCD server

### Triggering Tekton Pipelines
Configure a Tekton webhook via EventListener, TriggerBinding and TriggerTemplate
# Chapter 13: Operationalizing ArgoCD
## High Availability
Enable HA mode in the Helm chart configuration (multi replicas or autoscaling with HPA)
## Scalibility

### Sharding
Sharding on Application controller level, focuses on the managed clusters => Applications in one cluster are synced by one Application controller
Sharding algos:
- legacy: uses UID-based distribution
- round-robin
`argocd admin cluster stats -n argocd`: sharding stats

Assign a cluster to a shard: `kubectl patch secret remote -n argocd --patch '{"stringData":{"shard":"1"}}'`
It’s recommended that you treat shard-to-cluster ratios in a 1:1 relationship on very busy systems. Another method is to have two to three shards handling all your preprod environments and have dedicated shards for each cluster in your prod environment.