Skip to content

Commit

Permalink
Merge pull request #24 from lablabs/fix_k8s_provider_issues
Browse files Browse the repository at this point in the history
Add dummy helm chart deployment option
  • Loading branch information
martinhaus authored Oct 8, 2021
2 parents b14f27f + 2ad4ad4 commit f010578
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 22 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ Check out these related projects.

See [Basic example](examples/basic/README.md) for further information.

## Potential issues with running terraform plan

When deploying with ArgoCD application, Kubernetes terraform provider requires access to Kubernetes cluster API during plan time. This introduces potential issue when you want to deploy the cluster with this addon at the same time, during the same Terraform run.

To overcome this issue, the module deploys the ArgoCD application object using the Helm provider, which does not require API access during plan. If you want to deploy the application using this workaround, you can set the `argo_application_use_helm` variable to `true`.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

Expand All @@ -51,12 +57,14 @@ No modules.
| [aws_iam_policy.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [helm_release.argocd_application](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource |
| [helm_release.external_dns](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource |
| [kubernetes_manifest.this](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource |
| [kubernetes_manifest.self](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource |
| [aws_iam_policy_document.external_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.external_dns_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.external_dns_irsa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
| [utils_deep_merge_yaml.argo_application_values](https://registry.terraform.io/providers/cloudposse/utils/latest/docs/data-sources/deep_merge_yaml) | data source |
| [utils_deep_merge_yaml.values](https://registry.terraform.io/providers/cloudposse/utils/latest/docs/data-sources/deep_merge_yaml) | data source |

## Inputs
Expand All @@ -67,6 +75,8 @@ No modules.
| <a name="input_cluster_identity_oidc_issuer_arn"></a> [cluster\_identity\_oidc\_issuer\_arn](#input\_cluster\_identity\_oidc\_issuer\_arn) | The OIDC Identity issuer ARN for the cluster that can be used to associate IAM roles with a service account | `string` | n/a | yes |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | The name of the cluster | `string` | n/a | yes |
| <a name="input_argo_application_enabled"></a> [argo\_application\_enabled](#input\_argo\_application\_enabled) | If set to true, the module will be deployed as ArgoCD application, otherwise it will be deployed as a Helm release | `bool` | `false` | no |
| <a name="input_argo_application_use_helm"></a> [argo\_application\_use\_helm](#input\_argo\_application\_use\_helm) | If set to true, the ArgoCD Application manifest will be deployed using Kubernetes provider as a Helm release. Otherwise it'll be deployed as a Kubernetes manifest. See Readme for more info | `bool` | `false` | no |
| <a name="input_argo_application_values"></a> [argo\_application\_values](#input\_argo\_application\_values) | Value overrides to use when deploying argo application object with helm | `string` | `""` | no |
| <a name="input_argo_destionation_server"></a> [argo\_destionation\_server](#input\_argo\_destionation\_server) | Destination server for ArgoCD Application | `string` | `"https://kubernetes.default.svc"` | no |
| <a name="input_argo_info"></a> [argo\_info](#input\_argo\_info) | ArgoCD info manifest parameter | `list` | <pre>[<br> {<br> "name": "terraform",<br> "value": "true"<br> }<br>]</pre> | no |
| <a name="input_argo_namespace"></a> [argo\_namespace](#input\_argo\_namespace) | Namespace to deploy ArgoCD application CRD to | `string` | `"argo"` | no |
Expand Down
67 changes: 46 additions & 21 deletions argo.tf
Original file line number Diff line number Diff line change
@@ -1,30 +1,55 @@
resource "kubernetes_manifest" "this" {
count = var.argo_application_enabled ? 1 : 0
locals {
argo_application_values = {
"project" : var.argo_project
"source" : {
"repoURL" : var.helm_repo_url
"chart" : var.helm_chart_name
"targetRevision" : var.helm_chart_version
"helm" : {
"releaseName" : var.helm_release_name
"parameters" : [for k, v in var.settings : tomap({ "forceString" : true, "name" : k, "value" : v })]
"values" : data.utils_deep_merge_yaml.values[0].output
}
}
"destination" : {
"server" : var.argo_destionation_server
"namespace" : var.k8s_namespace
}
"syncPolicy" : var.argo_sync_policy
"info" : var.argo_info
}
}

data "utils_deep_merge_yaml" "argo_application_values" {
count = var.enabled && var.argo_application_enabled && var.argo_application_use_helm ? 1 : 0
input = compact([
yamlencode(local.argo_application_values),
var.argo_application_values
])
}

resource "helm_release" "argocd_application" {
count = var.enabled && var.argo_application_enabled && var.argo_application_use_helm ? 1 : 0

chart = "${path.module}/helm/argocd-application"
name = var.helm_release_name
namespace = var.argo_namespace

values = [
data.utils_deep_merge_yaml.argo_application_values[0].output
]
}


resource "kubernetes_manifest" "self" {
count = var.enabled && var.argo_application_enabled && !var.argo_application_use_helm ? 1 : 0
manifest = {
"apiVersion" = "argoproj.io/v1alpha1"
"kind" = "Application"
"metadata" = {
"name" = var.helm_release_name
"namespace" = var.argo_namespace
}
"spec" = {
"project" = var.argo_project
"source" = {
"repoURL" = var.helm_repo_url
"chart" = var.helm_chart_name
"targetRevision" = var.helm_chart_version
"helm" = {
"releaseName" = var.helm_release_name
"parameters" = [for k, v in var.settings : tomap({ "forceString" : true, "name" : k, "value" : v })]
"values" = data.utils_deep_merge_yaml.values[0].output
}
}
"destination" = {
"server" = var.argo_destionation_server
"namespace" = var.k8s_namespace
}
"syncPolicy" = var.argo_sync_policy
"info" = var.argo_info
}
"spec" = local.argo_application_values
}
}
23 changes: 23 additions & 0 deletions helm/argocd-application/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
18 changes: 18 additions & 0 deletions helm/argocd-application/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v2
name: argocd-application
description: Helm wrapper for deploying ArgoCD application object

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
51 changes: 51 additions & 0 deletions helm/argocd-application/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "argocd_application.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "argocd_application.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "argocd_application.chart" -}}
{{- printf "%s" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "argocd_application.labels" -}}
helm.sh/chart: {{ include "argocd_application.chart" . }}
{{ include "argocd_application.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "argocd_application.selectorLabels" -}}
app.kubernetes.io/name: {{ include "argocd_application.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
24 changes: 24 additions & 0 deletions helm/argocd-application/templates/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ include "argocd_application.fullname" . }}
labels:
{{- include "argocd_application.labels" . | nindent 4 }}
spec:
project: {{ .Values.project }}
{{ with .Values.source }}
source:
{{- toYaml . | nindent 4 }}
{{- end }}
{{ with .Values.destination }}
destination:
{{- toYaml . | nindent 4 }}
{{- end }}
{{ with .Values.syncPolicy }}
syncPolicy:
{{- toYaml . | nindent 4 }}
{{- end }}
{{ with .Values.info }}
info:
{{- toYaml . | nindent 4 }}
{{- end }}
2 changes: 2 additions & 0 deletions helm/argocd-application/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
nameOverride: ""
fullnameOverride: ""
11 changes: 11 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ variable "argo_application_enabled" {
description = "If set to true, the module will be deployed as ArgoCD application, otherwise it will be deployed as a Helm release"
}

variable "argo_application_use_helm" {
type = bool
default = false
description = "If set to true, the ArgoCD Application manifest will be deployed using Kubernetes provider as a Helm release. Otherwise it'll be deployed as a Kubernetes manifest. See Readme for more info"
}

variable "argo_application_values" {
default = ""
description = "Value overrides to use when deploying argo application object with helm"
}

variable "argo_destionation_server" {
type = string
default = "https://kubernetes.default.svc"
Expand Down

0 comments on commit f010578

Please sign in to comment.