# PRD: Layer 45 - ArgoCD

**Scope:** Deployment account. ArgoCD installation and GitOps bootstrap.

**Dependencies:** PRD_00-cross-cutting, PRD_00-bootstrap, PRD_10-network, PRD_20-eks, PRD_40-platform (argocd namespace, secrets sync).

## 1. Purpose and Execution Order

| ID | Requirement |
| ---- | ------------- |
| R-A45-001 | This layer SHALL install ArgoCD (e.g. via Helm) into the `argocd` namespace. |
| R-A45-002 | The layer SHALL run after platform and before app-wikijs. |
| R-A45-003 | Outputs SHALL be published to Parameter Store: ArgoCD namespace and ArgoCD server URL (if exposed). |

## 2. ArgoCD Installation

| ID | Requirement |
| ---- | ------------- |
| R-A45-101 | ArgoCD SHALL be installed using Helm into the `argocd` namespace. |
| R-A45-102 | ArgoCD configuration SHALL support the GitOps workflow for the Wiki.js application (layer 50). |
| R-A45-103 | ArgoCD SHALL be configured to target the repository path and Helm chart used for Wiki.js (e.g. `apps/wikijs`). |

## 3. Access and Exposure

| ID | Requirement |
| ---- | ------------- |
| R-A45-201 | ArgoCD access SHALL be internal-only by default; external exposure SHALL require an explicit, separate change (e.g. set `argocd_server_fqdn` for subdomain exposure). |
| R-A45-202 | ArgoCD server URL (if exposed) SHALL be published to Parameter Store for documentation or integration purposes. When exposed via subdomain, the URL SHALL be `https://<argocd_server_fqdn>`. |
| R-A45-203 | When `argocd_server_fqdn` is set, the layer SHALL enable an Ingress with AWS ALB, TLS (ACM certificate from bootstrap), and SHALL optionally create a Route 53 A record in the domain account (same pattern as layer 50 for Wiki.js). |

## 4. Repository Credentials (Private Repo)

| ID | Requirement |
| ---- | ------------- |
| R-A45-301 | If the Git repository is private, repo access credentials (deploy key or token) SHALL be stored in AWS Secrets Manager only. |
| R-A45-302 | The repo credential secret SHALL be synced from Secrets Manager into the `argocd` namespace (e.g. via the platform secrets sync mechanism). |
| R-A45-303 | Terraform SHALL reference only the secret ARN and the Kubernetes secret name; Terraform SHALL NOT materialize or store the secret value. |

## 5. Parameter Store Outputs

| ID | Requirement |
| ---- | ------------- |
| R-A45-401 | The layer SHALL publish to Parameter Store under `wikijs/<region>/<env>/45-argocd/`: ArgoCD namespace and ArgoCD server URL (if exposed). When admin credentials are from Secrets Manager (auto-created or user-provided), it SHALL also publish `argocd_admin_credentials_secret_arn`. |
| R-A45-402 | The layer SHALL publish only under its own prefix. |

## 6. Destroy Behavior

| ID | Requirement |
| ---- | ------------- |
| R-A45-501 | On `terraform destroy`, the layer SHALL remove the ArgoCD installation and related resources after the app-wikijs layer (50) has been destroyed. |
| R-A45-502 | The layer SHALL delete its own Parameter Store prefix after successful destroy. |
| R-A45-503 | A provision workflow and a destroy workflow SHALL exist; destroy SHALL run after 50-app-wikijs. |

## 7. Implementation Notes

- **Terraform path:** `terraform/45-argocd`.
- **Workflows:** `tf-45-argocd-provision.yaml`, `tf-45-argocd-destroy.yaml` (extension `.yaml`).
- **Argo CD:** Official Helm chart `argo-cd` from <https://argoproj.github.io/argo-helm>; installed into the `argocd` namespace (created by layer 40-platform).
- **Internal-only default:** Server service type ClusterIP; Ingress disabled. Argo CD server URL published to Parameter Store (internal URL when not exposed).
- **External UI (subdomain):** Optional variable `argocd_server_fqdn` (e.g. `argocd.wikijs.talorlik.com`). When set: Ingress enabled with ALB, TLS (ACM from bootstrap), `server.insecure` for TLS termination at ingress; optional Route 53 A record via assumed DNS role (01-dns-main). Same pattern as layer 50 for Wiki.js. Parameter Store publishes `argocd_server_url` as `https://<argocd_server_fqdn>`. Route 53 record may require a second apply after ALB exists.
- **Admin credentials:** By default (`create_auto_argocd_admin_credentials = true`), Terraform auto-generates username (`admin`) and password, stores them in a new Secrets Manager secret, and syncs them into the cluster via SecretProviderClass and a one-off Job (with IRSA). You retrieve credentials from that secret (Parameter Store key `argocd_admin_credentials_secret_arn` gives the secret ARN). Argo CD admin login accepts these credentials. To use an existing secret, set `create_auto_argocd_admin_credentials = false` and provide `argocd_admin_credentials_secret_arn` (secret must have `admin.password`, `admin.passwordMtime`, and optionally `username`, `password`).
- **Private repo:** Optional variable `repo_credentials_secret_arn`; repo credential secret synced from Secrets Manager into the argocd namespace via platform Secrets Store CSI driver (SecretProviderClass). Terraform references only the secret ARN; no secret value in code or state.
- **Parameter Store (writes):** `argocd_namespace`, `argocd_server_url` under `wikijs/<region>/<env>/45-argocd/`. When admin credentials are from Secrets Manager (auto-created or user-provided), also `argocd_admin_credentials_secret_arn` (use this ARN to retrieve username and password).
