Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ Examples:
- [ ] EKS root module
- [ ] Adopt terraform-docs for modules https://terraform-docs.io/
- [x] token-sa-kubeconfig module (working with EKS and GKE)
- [ ] educates-gitops module
- [x] educates-gitops module
- [ ] sample root-module with educates-gitops
7 changes: 7 additions & 0 deletions platform/educates-gitops/05-additional-files.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Install additional files if they are provided

# Install theme if file exists
resource "kubectl_manifest" "theme" {
count = fileexists(var.gitopsConfig.themeFile) ? 1 : 0
yaml_body = file(var.gitopsConfig.themeFile)
}
192 changes: 192 additions & 0 deletions platform/educates-gitops/10-educates-gitops-workshops.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#########
## educates ns and rbac
#########
resource "kubectl_manifest" "namespace_gitops_installs" {
yaml_body = <<YAML
apiVersion: v1
kind: Namespace
metadata:
name: "${var.gitopsApp.namespace}"
YAML

apply_only = true

wait_for {
field {
key = "status.phase"
value = "Active"
}
}
}

resource "kubectl_manifest" "serviceaccount_gitops_installs" {
yaml_body = <<YAML
apiVersion: v1
kind: ServiceAccount
metadata:
name: "${var.gitopsApp.namespace}"
namespace: "${var.gitopsApp.namespace}"
YAML

apply_only = true

depends_on = [
kubectl_manifest.namespace_gitops_installs
]
}

resource "kubectl_manifest" "clusterrolebinding_gitops_installs" {
yaml_body = <<YAML
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: "${var.gitopsApp.namespace}"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: "${var.gitopsApp.namespace}"
namespace: "${var.gitopsApp.namespace}"
YAML

apply_only = true

depends_on = [
# time_sleep.wait_for_kapp_controller,
kubectl_manifest.serviceaccount_gitops_installs
]
}


resource "time_sleep" "k8s_gitops_rbac" {
create_duration = "1s" # This time is used to wait for kapp-controller to be available
destroy_duration = "1s" # This time is used to make sure apps are deleted before the SA

depends_on = [
kubectl_manifest.namespace_gitops_installs,
kubectl_manifest.serviceaccount_gitops_installs,
kubectl_manifest.clusterrolebinding_gitops_installs
]
}

#########
## workshops
#########
locals {
workshop_gitops_config = try(file(var.gitopsApp.configFile), "#comment")
workshop_gitops_config_indented_encoded_string = indent(15, yamlencode(local.workshop_gitops_config))
}


#TODO: Make gitops username and password optional
# data "kubectl_path_documents" "app_gitops_manifests" {
# pattern = "${path.module}/manifests/workshop-gitops-app/*.yaml"
# vars = {
# k8s_gitops_namespace = var.k8s_gitops_namespace
# gitops_environment = var.gitops_environment
# gitops_config_syncperiod = var.gitops_config_syncperiod
# workshop_gitops_config = local.workshop_gitops_config_indented_encoded_string
# gitops_config_subpath_prefix = var.gitops_config_subpath_prefix
# gitops_config_repo = var.gitops_config_repo
# gitops_config_ref = var.gitops_config_ref
# gitops_overlays_bundle = var.gitops_overlays_bundle
# gitops_github_username = var.gitops_github_username
# gitops_github_password = var.gitops_github_password
# }
# }

# resource "kubectl_manifest" "app_gitops_manifests_deploy" {
# for_each = try(data.kubectl_path_documents.app_gitops_manifests.manifests, toset([]))
# yaml_body = each.value

# depends_on = [
# time_sleep.k8s_gitops_rbac,
# # kubectl_manifest.educates_app
# ]
# }

resource "kubectl_manifest" "gitops_credentials" {
yaml_body = <<YAML
kind: Secret
apiVersion: v1
metadata:
name: "workshops-gitops-git-creds"
namespace: "${var.gitopsApp.namespace}"
type: Opaque
stringData:
username: "${var.gitopsConfig.github.username}"
password: "${var.gitopsConfig.github.password}"
YAML

depends_on = [time_sleep.k8s_gitops_rbac]
}

resource "kubectl_manifest" "gitops_app" {
yaml_body = <<YAML
apiVersion: kappctrl.k14s.io/v1alpha1
kind: App
metadata:
name: workshop-gitops
namespace: "${var.gitopsApp.namespace}"
annotations:
educates.gitops-workshops.subpath_prefix: "${var.gitopsConfig.subPathPrefix}"
educates.gitops-workshops.environment: "${var.gitopsConfig.environment}"
spec:
serviceAccountName: "${var.gitopsApp.namespace}"
syncPeriod: "${var.gitopsConfig.syncPeriod}"
fetch:
- inline:
paths:
globals.yaml: ${local.workshop_gitops_config_indented_encoded_string}
path: environment/globals
- image:
secretRef:
name: workshops-gitops-git-creds
subPath: gitops-app/src/bundle/config
url: "${var.gitopsConfig.overlaysBundle}"
path: config
- git:
ref: "${var.gitopsConfig.ref}"
secretRef:
name: workshops-gitops-git-creds
subPath: "${var.gitopsConfig.subPathPrefix}/${var.gitopsConfig.environment}"
url: "${var.gitopsConfig.configRepo}"
path: environment/versions
template:
- ytt:
ignoreUnknownComments: true
paths:
- config
valuesFrom:
- path: "environment/globals"
- path: "environment/versions/versions.yaml"
- downwardAPI:
items:
- name: config.subPath
fieldPath: "metadata.annotations['educates\\.gitops-workshops\\.subpath_prefix']"
- downwardAPI:
items:
- name: environment
fieldPath: "metadata.annotations['educates\\.gitops-workshops\\.environment']"
deploy:
- kapp:
rawOptions: ["--app-changes-max-to-keep=5", "--wait-timeout=5m"]
YAML

wait_for {
field {
key = "status.conditions.[0].type"
value = "ReconcileSucceeded"
}
field {
key = "status.conditions.[0].status"
value = "True"
}
}
depends_on = [
time_sleep.k8s_gitops_rbac,
kubectl_manifest.gitops_credentials,
]
}
46 changes: 46 additions & 0 deletions platform/educates-gitops/REAME.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Terraform module for Educates-gitops

This terraform module will deploy [Educates-gitops](https://github.com/educates/educates-workshop-gitops-configurer) on an Educates cluster as a Carvel Application

## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 , < 2.0.0 |
| <a name="requirement_kubectl"></a> [kubectl](#requirement\_kubectl) | 2.0.4 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_kubectl"></a> [kubectl](#provider\_kubectl) | 2.0.4 |
| <a name="provider_time"></a> [time](#provider\_time) | n/a |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [kubectl_manifest.clusterrolebinding_gitops_installs](https://registry.terraform.io/providers/alekc/kubectl/2.0.4/docs/resources/manifest) | resource |
| [kubectl_manifest.gitops_app](https://registry.terraform.io/providers/alekc/kubectl/2.0.4/docs/resources/manifest) | resource |
| [kubectl_manifest.gitops_credentials](https://registry.terraform.io/providers/alekc/kubectl/2.0.4/docs/resources/manifest) | resource |
| [kubectl_manifest.namespace_gitops_installs](https://registry.terraform.io/providers/alekc/kubectl/2.0.4/docs/resources/manifest) | resource |
| [kubectl_manifest.serviceaccount_gitops_installs](https://registry.terraform.io/providers/alekc/kubectl/2.0.4/docs/resources/manifest) | resource |
| [kubectl_manifest.theme](https://registry.terraform.io/providers/alekc/kubectl/2.0.4/docs/resources/manifest) | resource |
| [time_sleep.k8s_gitops_rbac](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_gitopsApp"></a> [gitopsApp](#input\_gitopsApp) | n/a | <pre>object({<br/> namespace = optional(string, "workshop-gitops")<br/> configFile = optional(string, "workshop-gitops-config.yaml")<br/> })</pre> | `{}` | no |
| <a name="input_gitopsConfig"></a> [gitopsConfig](#input\_gitopsConfig) | n/a | <pre>object({<br/> configRepo = optional(string, "https://github.com/educates/educates-workshop-gitops-configurer")<br/> environment = optional(string, "sample-environment")<br/> ref = optional(string, "origin/main")<br/> subPathPrefix = optional(string, "config")<br/> syncPeriod = optional(string, "0h10m0s")<br/> overlaysBundle = optional(string, "ghcr.io/educates/educates-workshop-gitops-configurer:main")<br/> github = optional(object({<br/> username = optional(string, "")<br/> password = optional(string, "")<br/> }))<br/> themeFile = optional(string, "theme.yaml")<br/> })</pre> | <pre>{<br/> "github": {}<br/>}</pre> | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_educates-gitops"></a> [educates-gitops](#output\_educates-gitops) | n/a |
6 changes: 6 additions & 0 deletions platform/educates-gitops/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
output "educates-gitops" {
value = {
is_kapp_controller_installed = true
# educates_version = local.educates_package
}
}
34 changes: 34 additions & 0 deletions platform/educates-gitops/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
variable "gitopsApp"{
type = object({
namespace = optional(string, "workshop-gitops")
configFile = optional(string, "workshop-gitops-config.yaml")
})
default = {
}
}

variable "gitopsConfig"{
type = object({
configRepo = optional(string, "https://github.com/educates/educates-workshop-gitops-configurer")
environment = optional(string, "sample-environment")
ref = optional(string, "origin/main")
subPathPrefix = optional(string, "config")
syncPeriod = optional(string, "0h10m0s")
overlaysBundle = optional(string, "ghcr.io/educates/educates-workshop-gitops-configurer:main")
github = optional(object({
username = optional(string, "")
password = optional(string, "")
}))
themeFile = optional(string, "theme.yaml")
})
default = {
github = {
}
}


validation {
condition = can(regex("^(\\d{1,2})h(\\d{1,2})m(\\d{1,2})s", var.gitopsConfig.syncPeriod))
error_message = "gitops_config_syncperiod must be a valid kapp-controller sync period (e.g. 12h0m0s or 1h or 10m) and always greater that 30s"
}
}
9 changes: 9 additions & 0 deletions platform/educates-gitops/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_providers {
kubectl = {
source = "alekc/kubectl"
version = "2.0.4"
}
}
required_version = ">= 1.5.7 , < 2.0.0"
}