├── .gitignore ├── .pre-commit-config.yaml ├── LICENSE ├── README.md ├── charts └── resources │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ └── resources.yaml │ └── values.yaml ├── main.tf ├── outputs.tf ├── tests └── complete │ ├── README.md │ ├── bootstrap │ ├── addons.yaml │ └── workloads.yaml │ ├── destroy.sh │ ├── main.tf │ ├── outputs.tf │ ├── variables.tf │ └── versions.tf ├── variables.tf └── versions.tf /.gitignore: -------------------------------------------------------------------------------- 1 | local/ 2 | build/ 3 | plan.out 4 | plan.out.json 5 | 6 | # Local .terraform directories 7 | .terraform/ 8 | 9 | # .tfstate files 10 | *.tfstate 11 | *.tfstate.* 12 | 13 | # Crash log files 14 | crash.log 15 | 16 | # Exclude all .tfvars files, which are likely to contain sentitive data, such as 17 | # password, private keys, and other secrets. These should not be part of version 18 | # control as they are data points which are potentially sensitive and subject 19 | # to change depending on the environment. 20 | # 21 | *.tfvars 22 | 23 | # Ignore override files as they are usually used to override resources locally and so 24 | # are not checked in 25 | override.tf 26 | override.tf.json 27 | *_override.tf 28 | *_override.tf.json 29 | 30 | # Include override files you do wish to add to version control using negated pattern 31 | # 32 | # !example_override.tf 33 | 34 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 35 | # example: *tfplan* 36 | 37 | # Ignore CLI configuration files 38 | .terraformrc 39 | terraform.rc 40 | .terraform.lock.hcl 41 | 42 | go.mod 43 | go.sum 44 | 45 | .DS_Store 46 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v4.4.0 4 | hooks: 5 | - id: trailing-whitespace 6 | args: ['--markdown-linebreak-ext=md'] 7 | - id: end-of-file-fixer 8 | - id: check-merge-conflict 9 | - id: detect-private-key 10 | - repo: https://github.com/antonbabenko/pre-commit-terraform 11 | rev: v1.77.1 12 | hooks: 13 | - id: terraform_fmt 14 | - id: terraform_docs 15 | args: 16 | - '--args=--lockfile=false' 17 | - id: terraform_tflint 18 | args: 19 | - '--args=--only=terraform_deprecated_interpolation' 20 | - '--args=--only=terraform_deprecated_index' 21 | - '--args=--only=terraform_unused_declarations' 22 | - '--args=--only=terraform_comment_syntax' 23 | - '--args=--only=terraform_documented_outputs' 24 | - '--args=--only=terraform_documented_variables' 25 | - '--args=--only=terraform_typed_variables' 26 | - '--args=--only=terraform_module_pinned_source' 27 | - '--args=--only=terraform_naming_convention' 28 | - '--args=--only=terraform_required_version' 29 | - '--args=--only=terraform_required_providers' 30 | - '--args=--only=terraform_standard_module_structure' 31 | - '--args=--only=terraform_workspace_remote' 32 | - '--args=--only=terraform_empty_list_equality' 33 | - '--args=--only=terraform_unused_required_providers' 34 | - id: terraform_validate 35 | 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ARCHIVED REPOSITORY: Create issues and PRs in the new repository 2 | - The new location is here: https://github.com/gitops-bridge-dev/terraform-helm-gitops-bridge 3 | - The module is published on Terraform registry here: https://registry.terraform.io/modules/gitops-bridge-dev/gitops-bridge/helm/latest 4 | 5 | # gitops-bridge-argocd-bootstrap-terraform 6 | Terraform module for gitops-bridge argocd bootstrap 7 | 8 | It handles three aspect of ArgoCD bootstrap 9 | 1. Installs an intial deployment of argocd, this deployment (gets replaced by argocd applicationset) 10 | 2. Creates the ArgoCD cluster secret (including in-cluster) 11 | 3. Creates the intial set App of Apps (addons, workloads, etc.) 12 | 13 | To be use with [gitops-bridge](https://github.com/gitops-bridge-dev/) project, see example [here](https://github.com/gitops-bridge-dev/gitops-bridge/blob/main/argocd/iac/terraform/examples/eks/hello-world/main.tf) 14 | 15 | ## Usage 16 | 17 | ```hcl 18 | 19 | locals { 20 | name = "ex-${replace(basename(path.cwd), "_", "-")}" 21 | environment = "dev" 22 | cluster_version = "1.27" 23 | gitops_addons_url = "https://github.com/gitops-bridge-dev/gitops-bridge-argocd-control-plane-template" 24 | gitops_addons_basepath = "" 25 | gitops_addons_path = "bootstrap/control-plane/addons" 26 | gitops_addons_revision = "HEAD" 27 | 28 | oss_addons = { 29 | enable_argo_workflows = true 30 | enable_foo = true # you can add any addon here, make sure to update the gitops repo with the corresponding application set 31 | } 32 | addons = merge(local.oss_addons, { kubernetes_version = local.cluster_version }) 33 | 34 | addons_metadata = merge( 35 | { 36 | addons_repo_url = local.gitops_addons_url 37 | addons_repo_basepath = local.gitops_addons_basepath 38 | addons_repo_path = local.gitops_addons_path 39 | addons_repo_revision = local.gitops_addons_revision 40 | } 41 | ) 42 | 43 | argocd_apps = { 44 | addons = file("${path.module}/bootstrap/addons.yaml") 45 | workloads = file("${path.module}/bootstrap/workloads.yaml") 46 | } 47 | 48 | } 49 | 50 | ################################################################################ 51 | # GitOps Bridge: Bootstrap 52 | ################################################################################ 53 | module "gitops_bridge_bootstrap" { 54 | source = "github.com/gitops-bridge-dev/gitops-bridge-argocd-bootstrap-terraform?ref=v2.0.0" 55 | 56 | cluster = { 57 | cluster_name = local.name 58 | environment = local.environment 59 | metadata = local.addons_metadata 60 | addons = local.addons 61 | } 62 | apps = local.argocd_apps 63 | } 64 | 65 | ``` 66 | 67 | 68 | ## Requirements 69 | 70 | | Name | Version | 71 | |------|---------| 72 | | [terraform](#requirement\_terraform) | >= 1.0 | 73 | | [helm](#requirement\_helm) | >= 2.10.1 | 74 | | [kubernetes](#requirement\_kubernetes) | >= 2.22.0 | 75 | 76 | ## Providers 77 | 78 | | Name | Version | 79 | |------|---------| 80 | | [helm](#provider\_helm) | >= 2.10.1 | 81 | | [kubernetes](#provider\_kubernetes) | >= 2.22.0 | 82 | 83 | ## Modules 84 | 85 | No modules. 86 | 87 | ## Resources 88 | 89 | | Name | Type | 90 | |------|------| 91 | | [helm_release.argocd](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | 92 | | [helm_release.bootstrap](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | 93 | | [kubernetes_secret_v1.cluster](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret_v1) | resource | 94 | 95 | ## Inputs 96 | 97 | | Name | Description | Type | Default | Required | 98 | |------|-------------|------|---------|:--------:| 99 | | [apps](#input\_apps) | argocd app of apps to deploy | `any` | `{}` | no | 100 | | [argocd](#input\_argocd) | argocd helm options | `any` | `{}` | no | 101 | | [cluster](#input\_cluster) | argocd cluster secret | `any` | `null` | no | 102 | | [create](#input\_create) | Create terraform resources | `bool` | `true` | no | 103 | | [install](#input\_install) | Deploy argocd helm | `bool` | `true` | no | 104 | 105 | ## Outputs 106 | 107 | | Name | Description | 108 | |------|-------------| 109 | | [apps](#output\_apps) | ArgoCD apps | 110 | | [argocd](#output\_argocd) | Argocd helm release | 111 | | [cluster](#output\_cluster) | ArgoCD cluster | 112 | 113 | -------------------------------------------------------------------------------- /charts/resources/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/resources/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: resources 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.0.0" 25 | -------------------------------------------------------------------------------- /charts/resources/templates/resources.yaml: -------------------------------------------------------------------------------- 1 | {{ range .Values.resources }} 2 | --- 3 | {{ if typeIs "string" . }} 4 | {{- tpl . $ }} 5 | {{- else }} 6 | {{- toYaml . }} 7 | {{- end }} 8 | {{ end }} 9 | -------------------------------------------------------------------------------- /charts/resources/values.yaml: -------------------------------------------------------------------------------- 1 | ## Define Pure kubernetes resources 2 | # resources -- Define resources to be deployed by the raw chart 3 | resources: [] 4 | # - apiVersion: argoproj.io/v1alpha1 5 | # kind: ApplicationSet 6 | # metadata: 7 | # name: bootstrap-addons 8 | # namespace: argocd 9 | # spec: 10 | # syncPolicy: 11 | # preserveResourcesOnDeletion: true 12 | # generators: 13 | # - clusters: 14 | # selector: 15 | # matchExpressions: 16 | # - key: akuity.io/argo-cd-cluster-name 17 | # operator: NotIn 18 | # values: [in-cluster] 19 | # template: 20 | # metadata: 21 | # name: 'bootstrap-addons' 22 | # spec: 23 | # project: default 24 | # source: 25 | # repoURL: '{{metadata.annotations.addons_repo_url}}' 26 | # path: '{{metadata.annotations.addons_repo_basepath}}{{metadata.annotations.addons_repo_path}}' 27 | # targetRevision: '{{metadata.annotations.addons_repo_revision}}' 28 | # directory: 29 | # recurse: true 30 | # exclude: exclude/* 31 | # destination: 32 | # namespace: 'argocd' 33 | # name: '{{name}}' 34 | # syncPolicy: 35 | # automated: {} 36 | # - | 37 | # apiVersion: argoproj.io/v1alpha1 38 | # kind: ApplicationSet 39 | # metadata: 40 | # name: bootstrap-addons 41 | # namespace: argocd 42 | # spec: 43 | # syncPolicy: 44 | # preserveResourcesOnDeletion: true 45 | # generators: 46 | # - clusters: 47 | # selector: 48 | # matchExpressions: 49 | # - key: akuity.io/argo-cd-cluster-name 50 | # operator: NotIn 51 | # values: [in-cluster] 52 | # template: 53 | # metadata: 54 | # name: 'bootstrap-addons' 55 | # spec: 56 | # project: default 57 | # source: 58 | # repoURL: '{{metadata.annotations.addons_repo_url}}' 59 | # path: '{{metadata.annotations.addons_repo_basepath}}{{metadata.annotations.addons_repo_path}}' 60 | # targetRevision: '{{metadata.annotations.addons_repo_revision}}' 61 | # directory: 62 | # recurse: true 63 | # exclude: exclude/* 64 | # destination: 65 | # namespace: 'argocd' 66 | # name: '{{name}}' 67 | # syncPolicy: 68 | # automated: {} 69 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Install ArgoCD 3 | ################################################################################ 4 | resource "helm_release" "argocd" { 5 | count = var.create && var.install ? 1 : 0 6 | 7 | # https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/Chart.yaml 8 | # (there is no offical helm chart for argocd) 9 | name = try(var.argocd.name, "argo-cd") 10 | description = try(var.argocd.description, "A Helm chart to install the ArgoCD") 11 | namespace = try(var.argocd.namespace, "argocd") 12 | create_namespace = try(var.argocd.create_namespace, true) 13 | chart = try(var.argocd.chart, "argo-cd") 14 | version = try(var.argocd.chart_version, "5.45.0") 15 | repository = try(var.argocd.repository, "https://argoproj.github.io/argo-helm") 16 | values = try(var.argocd.values, []) 17 | 18 | timeout = try(var.argocd.timeout, null) 19 | repository_key_file = try(var.argocd.repository_key_file, null) 20 | repository_cert_file = try(var.argocd.repository_cert_file, null) 21 | repository_ca_file = try(var.argocd.repository_ca_file, null) 22 | repository_username = try(var.argocd.repository_username, null) 23 | repository_password = try(var.argocd.repository_password, null) 24 | devel = try(var.argocd.devel, null) 25 | verify = try(var.argocd.verify, null) 26 | keyring = try(var.argocd.keyring, null) 27 | disable_webhooks = try(var.argocd.disable_webhooks, null) 28 | reuse_values = try(var.argocd.reuse_values, null) 29 | reset_values = try(var.argocd.reset_values, null) 30 | force_update = try(var.argocd.force_update, null) 31 | recreate_pods = try(var.argocd.recreate_pods, null) 32 | cleanup_on_fail = try(var.argocd.cleanup_on_fail, null) 33 | max_history = try(var.argocd.max_history, null) 34 | atomic = try(var.argocd.atomic, null) 35 | skip_crds = try(var.argocd.skip_crds, null) 36 | render_subchart_notes = try(var.argocd.render_subchart_notes, null) 37 | disable_openapi_validation = try(var.argocd.disable_openapi_validation, null) 38 | wait = try(var.argocd.wait, true) 39 | wait_for_jobs = try(var.argocd.wait_for_jobs, null) 40 | dependency_update = try(var.argocd.dependency_update, null) 41 | replace = try(var.argocd.replace, null) 42 | lint = try(var.argocd.lint, null) 43 | 44 | dynamic "postrender" { 45 | for_each = length(try(var.argocd.postrender, {})) > 0 ? [var.argocd.postrender] : [] 46 | 47 | content { 48 | binary_path = postrender.value.binary_path 49 | args = try(postrender.value.args, null) 50 | } 51 | } 52 | 53 | dynamic "set" { 54 | for_each = try(var.argocd.set, []) 55 | 56 | content { 57 | name = set.value.name 58 | value = set.value.value 59 | type = try(set.value.type, null) 60 | } 61 | } 62 | 63 | dynamic "set_sensitive" { 64 | for_each = try(var.argocd.set_sensitive, []) 65 | 66 | content { 67 | name = set_sensitive.value.name 68 | value = set_sensitive.value.value 69 | type = try(set_sensitive.value.type, null) 70 | } 71 | } 72 | 73 | } 74 | 75 | 76 | ################################################################################ 77 | # ArgoCD Cluster 78 | ################################################################################ 79 | locals { 80 | cluster_name = try(var.cluster.cluster_name, "in-cluster") 81 | environment = try(var.cluster.environment, "dev") 82 | argocd_labels = merge({ 83 | cluster_name = local.cluster_name 84 | environment = local.environment 85 | enable_argocd = true 86 | "argocd.argoproj.io/secret-type" = "cluster" 87 | }, 88 | try(var.cluster.addons, {}) 89 | ) 90 | argocd_annotations = merge( 91 | { 92 | cluster_name = local.cluster_name 93 | environment = local.environment 94 | }, 95 | try(var.cluster.metadata, {}) 96 | ) 97 | } 98 | 99 | locals { 100 | config = <<-EOT 101 | { 102 | "tlsClientConfig": { 103 | "insecure": false 104 | } 105 | } 106 | EOT 107 | argocd = { 108 | apiVersion = "v1" 109 | kind = "Secret" 110 | metadata = { 111 | name = try(var.cluster.secret_name, local.cluster_name) 112 | namespace = try(var.cluster.secret_namespace, "argocd") 113 | annotations = local.argocd_annotations 114 | labels = local.argocd_labels 115 | } 116 | stringData = { 117 | name = local.cluster_name 118 | server = try(var.cluster.server, "https://kubernetes.default.svc") 119 | config = try(var.cluster.config, local.config) 120 | } 121 | } 122 | } 123 | resource "kubernetes_secret_v1" "cluster" { 124 | count = var.create && (var.cluster != null) ? 1 : 0 125 | 126 | metadata { 127 | name = local.argocd.metadata.name 128 | namespace = local.argocd.metadata.namespace 129 | annotations = local.argocd.metadata.annotations 130 | labels = local.argocd.metadata.labels 131 | } 132 | data = local.argocd.stringData 133 | 134 | depends_on = [helm_release.argocd] 135 | } 136 | 137 | 138 | ################################################################################ 139 | # Create App of Apps 140 | ################################################################################ 141 | resource "helm_release" "bootstrap" { 142 | for_each = var.create ? var.apps : {} 143 | 144 | name = each.key 145 | namespace = try(var.argocd.namespace, "argocd") 146 | chart = "${path.module}/charts/resources" 147 | version = "1.0.0" 148 | 149 | values = [ 150 | <<-EOT 151 | resources: 152 | - ${indent(4, each.value)} 153 | EOT 154 | ] 155 | 156 | depends_on = [resource.kubernetes_secret_v1.cluster] 157 | } 158 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "argocd" { 2 | description = "Argocd helm release" 3 | value = try(helm_release.argocd[0], null) 4 | } 5 | output "cluster" { 6 | description = "ArgoCD cluster" 7 | value = try(kubernetes_secret_v1.cluster[0], null) 8 | } 9 | output "apps" { 10 | description = "ArgoCD apps" 11 | value = try(helm_release.bootstrap, null) 12 | } 13 | -------------------------------------------------------------------------------- /tests/complete/README.md: -------------------------------------------------------------------------------- 1 | # Test argocd bootstrap 2 | 3 | ## Requirements 4 | 1. helm 5 | 2. kubernetes kubeconfig setup 6 | 7 | Create kubernetes cluster you can use `kind` 8 | ```shell 9 | kind create cluster 10 | ``` 11 | 12 | ## Bootstrap ArgoCD 13 | 14 | ```shell 15 | terraform init 16 | terraform apply 17 | ``` 18 | 19 | Access Terraform output to configure `kubectl` and `argocd` 20 | ```shell 21 | terraform output 22 | ``` 23 | 24 | Destroy 25 | ```shell 26 | terraform destroy 27 | ``` 28 | -------------------------------------------------------------------------------- /tests/complete/bootstrap/addons.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: bootstrap-addons 5 | namespace: argocd 6 | spec: 7 | syncPolicy: 8 | preserveResourcesOnDeletion: true 9 | generators: 10 | - clusters: 11 | selector: 12 | matchExpressions: 13 | - key: akuity.io/argo-cd-cluster-name 14 | operator: NotIn 15 | values: [in-cluster] 16 | template: 17 | metadata: 18 | name: 'bootstrap-addons' 19 | spec: 20 | project: default 21 | source: 22 | repoURL: '{{metadata.annotations.addons_repo_url}}' 23 | path: '{{metadata.annotations.addons_repo_basepath}}{{metadata.annotations.addons_repo_path}}' 24 | targetRevision: '{{metadata.annotations.addons_repo_revision}}' 25 | directory: 26 | recurse: true 27 | exclude: exclude/* 28 | destination: 29 | namespace: 'argocd' 30 | name: '{{name}}' 31 | syncPolicy: 32 | automated: {} 33 | -------------------------------------------------------------------------------- /tests/complete/bootstrap/workloads.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: bootstrap-workloads 5 | namespace: 'argocd' 6 | finalizers: 7 | - resources-finalizer.argocd.argoproj.io 8 | spec: 9 | destination: 10 | server: https://kubernetes.default.svc 11 | namespace: 'guestbook' 12 | project: default 13 | source: 14 | path: helm-guestbook 15 | repoURL: https://github.com/argoproj/argocd-example-apps 16 | targetRevision: HEAD 17 | syncPolicy: 18 | automated: {} 19 | syncOptions: 20 | - CreateNamespace=true 21 | -------------------------------------------------------------------------------- /tests/complete/destroy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | # Delete the Ingress/SVC before removing the addons 6 | TMPFILE=$(mktemp) 7 | terraform output -raw configure_kubectl > "$TMPFILE" 8 | source "$TMPFILE" 9 | 10 | kubectl delete svc -n argocd argo-cd-argocd-server 11 | 12 | terraform destroy -target="module.gitops_bridge_bootstrap" -auto-approve 13 | terraform destroy -target="module.eks_blueprints_addons" -auto-approve 14 | terraform destroy -target="module.eks" -auto-approve 15 | terraform destroy -target="module.vpc" -auto-approve 16 | terraform destroy -auto-approve 17 | -------------------------------------------------------------------------------- /tests/complete/main.tf: -------------------------------------------------------------------------------- 1 | 2 | provider "helm" { 3 | kubernetes { 4 | config_path = "~/.kube/config" 5 | } 6 | } 7 | provider "kubectl" { 8 | config_path = "~/.kube/config" 9 | } 10 | provider "kubernetes" { 11 | config_path = "~/.kube/config" 12 | } 13 | 14 | locals { 15 | name = "ex-${replace(basename(path.cwd), "_", "-")}" 16 | environment = "dev" 17 | cluster_version = "1.27" 18 | gitops_addons_url = "https://github.com/gitops-bridge-dev/gitops-bridge-argocd-control-plane-template" 19 | gitops_addons_basepath = "" 20 | gitops_addons_path = "bootstrap/control-plane/addons" 21 | gitops_addons_revision = "HEAD" 22 | 23 | oss_addons = { 24 | #enable_argo_rollouts = true 25 | enable_argo_workflows = true 26 | #enable_cluster_proportional_autoscaler = true 27 | #enable_gatekeeper = true 28 | #enable_gpu_operator = true 29 | #enable_ingress_nginx = true 30 | #enable_kyverno = true 31 | #enable_kube_prometheus_stack = true 32 | #enable_metrics_server = true 33 | #enable_prometheus_adapter = true 34 | #enable_secrets_store_csi_driver = true 35 | #enable_vpa = true 36 | #enable_foo = true # you can add any addon here, make sure to update the gitops repo with the corresponding application set 37 | } 38 | addons = merge(local.oss_addons, { kubernetes_version = local.cluster_version }) 39 | 40 | addons_metadata = merge( 41 | { 42 | addons_repo_url = local.gitops_addons_url 43 | addons_repo_basepath = local.gitops_addons_basepath 44 | addons_repo_path = local.gitops_addons_path 45 | addons_repo_revision = local.gitops_addons_revision 46 | } 47 | ) 48 | 49 | argocd_apps = { 50 | addons = file("${path.module}/bootstrap/addons.yaml") 51 | workloads = file("${path.module}/bootstrap/workloads.yaml") 52 | } 53 | 54 | } 55 | 56 | 57 | ################################################################################ 58 | # GitOps Bridge: Bootstrap 59 | ################################################################################ 60 | module "gitops_bridge_bootstrap" { 61 | source = "../../" 62 | 63 | cluster = { 64 | cluster_name = local.name 65 | environment = local.environment 66 | metadata = local.addons_metadata 67 | addons = local.addons 68 | } 69 | apps = local.argocd_apps 70 | } 71 | -------------------------------------------------------------------------------- /tests/complete/outputs.tf: -------------------------------------------------------------------------------- 1 | output "argocd" { 2 | description = "test argocd output" 3 | value = module.gitops_bridge_bootstrap.argocd 4 | sensitive = true 5 | } 6 | output "cluster" { 7 | description = "test cluster output" 8 | value = module.gitops_bridge_bootstrap.cluster 9 | sensitive = true 10 | } 11 | output "apps" { 12 | description = "test apps output" 13 | value = module.gitops_bridge_bootstrap.apps 14 | sensitive = true 15 | } 16 | 17 | 18 | 19 | output "configure_argocd" { 20 | description = "Terminal Setup" 21 | value = <<-EOT 22 | export ARGOCD_OPTS="--port-forward --port-forward-namespace argocd --grpc-web" 23 | kubectl config set-context --current --namespace argocd 24 | argocd login --port-forward --username admin --password $(argocd admin initial-password | head -1) 25 | echo "ArgoCD Username: admin" 26 | echo "ArgoCD Password: $(kubectl get secrets argocd-initial-admin-secret -n argocd --template="{{index .data.password | base64decode}}")" 27 | echo Port Forward: http://localhost:8080 28 | kubectl port-forward -n argocd svc/argo-cd-argocd-server 8080:80 29 | EOT 30 | } 31 | -------------------------------------------------------------------------------- /tests/complete/variables.tf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitops-bridge-dev/gitops-bridge-argocd-bootstrap-terraform/b78f5616b001a1563fee891e8f703d0d75c6e43d/tests/complete/variables.tf -------------------------------------------------------------------------------- /tests/complete/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.0" 3 | 4 | required_providers { 5 | helm = { 6 | source = "hashicorp/helm" 7 | version = ">= 2.10.1" 8 | } 9 | kubernetes = { 10 | source = "hashicorp/kubernetes" 11 | version = ">= 2.22.0" 12 | } 13 | } 14 | 15 | # ## Used for end-to-end testing on project; update to suit your needs 16 | # backend "s3" { 17 | # bucket = "terraform-ssp-github-actions-state" 18 | # region = "us-west-2" 19 | # key = "e2e/ipv4-prefix-delegation/terraform.tfstate" 20 | # } 21 | } 22 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "create" { 2 | description = "Create terraform resources" 3 | type = bool 4 | default = true 5 | } 6 | variable "argocd" { 7 | description = "argocd helm options" 8 | type = any 9 | default = {} 10 | } 11 | variable "install" { 12 | description = "Deploy argocd helm" 13 | type = bool 14 | default = true 15 | } 16 | 17 | variable "cluster" { 18 | description = "argocd cluster secret" 19 | type = any 20 | default = null 21 | } 22 | 23 | variable "apps" { 24 | description = "argocd app of apps to deploy" 25 | type = any 26 | default = {} 27 | } 28 | -------------------------------------------------------------------------------- /versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.0" 3 | 4 | required_providers { 5 | helm = { 6 | source = "hashicorp/helm" 7 | version = ">= 2.10.1" 8 | } 9 | kubernetes = { 10 | source = "hashicorp/kubernetes" 11 | version = ">= 2.22.0" 12 | } 13 | } 14 | 15 | # ## Used for end-to-end testing on project; update to suit your needs 16 | # backend "s3" { 17 | # bucket = "terraform-ssp-github-actions-state" 18 | # region = "us-west-2" 19 | # key = "e2e/ipv4-prefix-delegation/terraform.tfstate" 20 | # } 21 | } 22 | --------------------------------------------------------------------------------