diff --git a/.gitignore b/.gitignore index edeabaf..7c91e9c 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,4 @@ github/ *.ovpn *.zip +account-map/ diff --git a/src/README.md b/src/README.md index 0d1160c..2339b8b 100644 --- a/src/README.md +++ b/src/README.md @@ -630,16 +630,15 @@ Reference: https://stackoverflow.com/questions/75046330/argo-cd-error-server-sec ## References -- [Argo CD](https://argoproj.github.io/cd/) - +- [Argo CD](https://argoproj.github.io/cd/) - -- [Argo CD Docs](https://argo-cd.readthedocs.io/en/stable/) - +- [Argo CD Docs](https://argo-cd.readthedocs.io/en/stable/) - -- [Argo Helm Chart](https://github.com/argoproj/argo-helm/blob/master/charts/argo-cd/) - +- [Argo Helm Chart](https://github.com/argoproj/argo-helm/blob/master/charts/argo-cd/) - -- [Argo CD error "server.secretkey is missing"](https://stackoverflow.com/questions/75046330/argo-cd-error-server-secretkey-is-missing) - +- [Argo CD error "server.secretkey is missing"](https://stackoverflow.com/questions/75046330/argo-cd-error-server-secretkey-is-missing) - [](https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse-terraform-components/aws-eks-argocd&utm_content=) - diff --git a/src/data.tf b/src/data.tf index 212c20e..cc1d2c0 100644 --- a/src/data.tf +++ b/src/data.tf @@ -26,7 +26,7 @@ data "aws_ssm_parameter" "oidc_client_secret" { } data "aws_ssm_parameter" "github_deploy_key" { - for_each = local.enabled ? var.argocd_repositories : {} + for_each = local.github_deploy_keys_enabled ? var.argocd_repositories : {} name = local.enabled ? format( module.argocd_repo[each.key].outputs.deploy_keys_ssm_path_format, diff --git a/src/main.tf b/src/main.tf index 8ffc578..2d05857 100644 --- a/src/main.tf +++ b/src/main.tf @@ -1,41 +1,50 @@ locals { enabled = module.this.enabled - kubernetes_namespace = var.kubernetes_namespace - oidc_enabled = local.enabled && var.oidc_enabled - oidc_enabled_count = local.oidc_enabled ? 1 : 0 - saml_enabled = local.enabled && var.saml_enabled + kubernetes_namespace = var.kubernetes_namespace + oidc_enabled = local.enabled && var.oidc_enabled + oidc_enabled_count = local.oidc_enabled ? 1 : 0 + saml_enabled = local.enabled && var.saml_enabled + github_deploy_keys_enabled = local.enabled && var.github_deploy_keys_enabled argocd_repositories = local.enabled ? { for k, v in var.argocd_repositories : replace(k, "/", "-") => { - clone_url = module.argocd_repo[k].outputs.repository_ssh_clone_url - github_deploy_key = data.aws_ssm_parameter.github_deploy_key[k].value + # If using deploy keys, use the SSH clone URL. Otherwise, use the HTTP clone URL. + clone_url = local.github_deploy_keys_enabled ? module.argocd_repo[k].outputs.repository_ssh_clone_url : module.argocd_repo[k].outputs.repository_http_clone_url + github_deploy_key = local.github_deploy_keys_enabled ? data.aws_ssm_parameter.github_deploy_key[k].value : "" repository = module.argocd_repo[k].outputs.repository } } : {} - credential_templates = flatten(concat([ - for k, v in local.argocd_repositories : [ - { + credential_templates = flatten(concat( + [ + for k, v in local.argocd_repositories : { name = "configs.credentialTemplates.${k}.url" value = v.clone_url type = "string" - }, - { + } + ], + local.github_deploy_keys_enabled ? [ + for k, v in local.argocd_repositories : { name = "configs.credentialTemplates.${k}.sshPrivateKey" value = nonsensitive(v.github_deploy_key) type = "string" - }, - ] + } + ] : [ + # If we're using GitHub App authentication, we need to add the GitHub App private key as a secret. + # It will be used by all desired state repositories + for k, v in local.argocd_repositories : { + name = "configs.credentialTemplates.${k}.githubAppPrivateKey" + value = nonsensitive(data.aws_ssm_parameter.github_app_private_key[0].value) + type = "string" + } ], [ for s, v in local.notifications_notifiers_ssm_configs : [ - for k, i in v : [ - { - name = "notifications.secret.items.${s}_${k}" - value = i - type = "string" - } - ] + for k, i in v : { + name = "notifications.secret.items.${s}_${k}" + value = i + type = "string" + } ] ], local.github_webhook_enabled ? [ @@ -154,26 +163,29 @@ module "argocd" { templatefile( "${path.module}/resources/argocd-values.yaml.tpl", { - admin_enabled = var.admin_enabled - anonymous_enabled = var.anonymous_enabled - alb_group_name = var.alb_group_name == null ? "" : var.alb_group_name - alb_logs_bucket = var.alb_logs_bucket - alb_logs_prefix = var.alb_logs_prefix - alb_name = var.alb_name == null ? "" : var.alb_name - application_repos = { for k, v in local.argocd_repositories : k => v.clone_url } - argocd_host = local.host - cert_issuer = var.certificate_issuer - forecastle_enabled = var.forecastle_enabled - ingress_host = local.host - name = module.this.name - oidc_enabled = local.oidc_enabled - oidc_rbac_scopes = var.oidc_rbac_scopes - saml_enabled = local.saml_enabled - saml_rbac_scopes = var.saml_rbac_scopes - service_type = var.service_type - rbac_default_policy = var.argocd_rbac_default_policy - rbac_policies = var.argocd_rbac_policies - rbac_groups = var.argocd_rbac_groups + admin_enabled = var.admin_enabled + alb_group_name = var.alb_group_name == null ? "" : var.alb_group_name + alb_logs_bucket = var.alb_logs_bucket + alb_logs_prefix = var.alb_logs_prefix + alb_name = var.alb_name == null ? "" : var.alb_name + anonymous_enabled = var.anonymous_enabled + application_repos = { for k, v in local.argocd_repositories : k => v.clone_url } + argocd_host = local.host + cert_issuer = var.certificate_issuer + forecastle_enabled = var.forecastle_enabled + github_app_id = var.github_app_id + github_app_installation_id = var.github_app_installation_id + github_deploy_keys_enabled = local.github_deploy_keys_enabled + ingress_host = local.host + name = module.this.name + oidc_enabled = local.oidc_enabled + oidc_rbac_scopes = var.oidc_rbac_scopes + rbac_default_policy = var.argocd_rbac_default_policy + rbac_groups = var.argocd_rbac_groups + rbac_policies = var.argocd_rbac_policies + saml_enabled = local.saml_enabled + saml_rbac_scopes = var.saml_rbac_scopes + service_type = var.service_type } ), # argocd-notifications specific settings diff --git a/src/notifications.tf b/src/notifications.tf index e02fcdd..e0485f9 100644 --- a/src/notifications.tf +++ b/src/notifications.tf @@ -219,7 +219,7 @@ locals { if key != "ssm_path_prefix" && key != "webhook" }, { - for key, value in try(local.notifications_notifiers.webhook, {}) : + for key, value in coalesce(lookup(local.notifications_notifiers, "webhook", {}), {}) : format("webhook_%s", key) => { for param_name, param_value in value : param_name => param_value if param_value != null } } diff --git a/src/resources/argocd-values.yaml.tpl b/src/resources/argocd-values.yaml.tpl index 3e9d5db..6693d56 100644 --- a/src/resources/argocd-values.yaml.tpl +++ b/src/resources/argocd-values.yaml.tpl @@ -86,9 +86,17 @@ server: repositories: | %{ for name, url in application_repos ~} - url: ${url} +%{ if github_deploy_keys_enabled == true ~} sshPrivateKeySecret: name: argocd-repo-creds-${name} key: sshPrivateKey +%{ else ~} + githubAppID: ${tonumber(github_app_id)} + githubAppInstallationID: ${tonumber(github_app_installation_id)} + githubAppPrivateKeySecret: + name: argocd-repo-creds-${name} + key: githubAppPrivateKey +%{ endif ~} %{ endfor ~} resource.customizations: | admissionregistration.k8s.io/MutatingWebhookConfiguration: @@ -122,13 +130,12 @@ server: %{ if oidc_enabled == true ~} scopes: '${oidc_rbac_scopes}' -%{ endif ~} -%{ if saml_enabled == true ~} +%{ else ~} +%{ if saml_enabled == true ~} scopes: '${saml_rbac_scopes}' +%{ endif ~} %{ endif ~} - policy.default: role:readonly - repoServer: replicas: 2 diff --git a/src/variables-argocd.tf b/src/variables-argocd.tf index 5ae2acc..6d1ca77 100644 --- a/src/variables-argocd.tf +++ b/src/variables-argocd.tf @@ -215,3 +215,13 @@ variable "saml_sso_providers" { default = {} description = "SAML SSO providers components" } + +variable "github_deploy_keys_enabled" { + type = bool + default = true + description = <<-EOT + Enable GitHub deploy keys for the repository. These are used for Argo CD application syncing. + + Alternatively, you can use a GitHub App to access this desired state repository configured with `var.github_app_enabled`, `var.github_app_id`, and `var.github_app_installation_id`. + EOT +}