Skip to content

Commit

Permalink
kubernetes deployment using mdxc and the massdriver-application module (
Browse files Browse the repository at this point in the history
#19)

* WIP

* moving chart

* working through it

* remove todos

* confirmed this works w/ | w/o .Connections

* helm bits

* helm

* k8s

* k8s

* k8s template!
  • Loading branch information
coryodaniel committed Aug 24, 2022
1 parent 34be5a0 commit 0b46e5e
Show file tree
Hide file tree
Showing 13 changed files with 129 additions and 184 deletions.
13 changes: 13 additions & 0 deletions kubernetes-deployment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# <md .Name md>

<md .Description md>

## Massdriver `kubernetes-deployment` Template

The `kubernetes-deployment` template will run your application on AWS, GCP, or Azure Kubernetes.

**Files**:

* a [terraform module](./src) is included that configurings IAM permissions and sets up you environment variables. You likely _do not_ need to modify these files. This module is simply rigging code to integrate with Massdriver Cloud.
* a [helm chart](./src/chart) has been created to run a kubernetes deployment. This Helm chart is a great getting started point for deploying to Kubernetes. Feel free to modify the chart to customize your application deployment.
* the [`massdriver.yaml`] controls the UI to expose for configuring your application and its dependencies. By default there are a lof of fields in your [`params`](https://docs.massdriver.cloud/bundles/configuration#bundle-params) section, feel free to remove fields that you do not want exposed in your configuration form in Massdriver Cloud. Values that you do not want to change (e.g.: your image repository) can be hard coded in the [values.yaml](./src/chart/values.yaml) file.
79 changes: 57 additions & 22 deletions kubernetes-deployment/massdriver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,60 @@ ref: github.com/YOUR_ORG/<md .Name md>
access: private
type: application

app:
envs:
# Use jq expressions to build environment variables from input params or connections
LOG_LEVEL: .params.log_level
# MONGO_DSN: .connections.mongo_authentication.data.authentication.username + ":" + .connections.mongo_authentication.data.authentication.password + "@" + .connections.mongo_authentication.data.authentication.hostname + ":" + (.connections.mongo_authentication.data.authentication.port|tostring)
policies: []
# Use jq expressions to select policies from artifact security blocks
# - .connections.sqs.data.security.iam.subscribe

params:
properties:
name:
type: string
namespace:
title: Kubernetes Namespace
type: string
default: default
image:
title: Container Image
type: object
properties:
repository:
title: Repository
# Container repositories can be created or imported into massdriver at: https://app.massdriver.cloud/container-repositories
# You'll generally want to hard code your container repository in your bundle code, but it can be helpful to show it
# in your schema as well.
# If you need to allow an end-user developer to select the container repo, you can use our drop down widget documented here: https://docs.massdriver.cloud/bundles/custom-widgets-and-fields
description: "Container repository to use for this application."
type: string
sha:
type: string
enum:
- nginxdemos/hello
tag:
title: Tag
description:
type: string
resource_requests:
minLength: 1
default: latest
resourceRequests:
type: object
properties:
cpu:
title: CPU
description: The minimum CPU resources required for this application.
type: string
# TODO: use custom rjsf widget here
memory:
title: Memory
description: The minimum Memory resources required for this application.
type: string
# TODO: use custom rjsf widget here
port:
title: Port
description: The container port the application will listen on.
type: integer
autoscaling:
title: Horizonal Autoscaling
type: object
properties:
enabled:
Expand All @@ -46,50 +74,57 @@ params:
type: integer
default: 90
ingress:
title: Ingress
description: Configure the application for public internet accessibility
type: object
properties:
enabled:
title: Enable Public Internet Access
type: boolean
host:
title: Hostname
description: TBD, is this the right field name?
type: string
path:
type: string
default: '/'
envs:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
<md if not .Connections md>
connections:
properties: {}
<md end -md>

<md if .Connections md>
connections:
required:
- kubernetes_cluster
<md- range $key, $art:= .Connections md>
- <md $key md>
<md- end md>
oneOf:
- required: ["aws_authentication"]
- required: ["gcp_authentication"]
- required: ["azure_authentication"]
properties:
kubernetes_cluster:
$ref: massdriver/kubernetes-cluster
aws_authentication:
$ref: massdriver/aws-iam-role
gcp_authentication:
$ref: massdriver/gcp-service-account
azure_authentication:
$ref: massdriver/azure-service-principal
<md- range $key, $art:= .Connections md>
<md $key md>:
$ref: <md $art md>
<md- end md>
<md- end md>

ui:
## If you need to allow an end user to select the container repository at deploy time, our smart widget can be used.
## Additional documentation here: https://docs.massdriver.cloud/bundles/custom-widgets-and-fields
# image:
# repository:
# ui:field: "containerRepositoriesDropdown"
# cloud: "aws"
ui:order:
- name
- namespace
- image
- resource_requests
- autoscaling
- envs
- port
- ingress
autoscaling:
Expand Down
209 changes: 50 additions & 159 deletions kubernetes-deployment/src/_providers.tf
Original file line number Diff line number Diff line change
@@ -1,159 +1,50 @@
# AWS providers
# terraform {
# required_version = ">= 1.0"
# required_providers {
# massdriver = {
# source = "massdriver-cloud/massdriver"
# }
# jq = {
# source = "massdriver-cloud/jq"
# }
# aws = {
# source = "hashicorp/aws"
# }
# helm = {
# source = "hashicorp/helm"
# }
# }
# }

# locals {
# aws_authentication = module.k8s_application.connections.aws_authentication
# kubernetes_cluster = module.k8s_application.connections.kubernetes_cluster
# k8s_cluster_name = split("/", local.kubernetes_cluster.data.infrastructure.arn)[1]
# region_hack = split(":", local.kubernetes_cluster.data.infrastructure.arn)[3]
# }

# data "aws_eks_cluster" "cluster" {
# name = local.k8s_cluster_name
# }

# data "aws_eks_cluster_auth" "auth" {
# name = local.k8s_cluster_name
# }

# provider "aws" {
# region = local.region_hack
# assume_role {
# role_arn = local.aws_authentication.data.arn
# external_id = local.aws_authentication.data.external_id
# }
# default_tags {
# tags = module.k8s_application.params.md_metadata.default_tags
# }
# }

# provider "helm" {
# kubernetes {
# host = data.aws_eks_cluster.cluster.endpoint
# cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)
# # token = local.kubernetes_cluster.data.authentication.user.token
# # this returns a value that doesn't work for the cluster
# # I'm not sure if it's the creds I used in the AWS provider
# # but I tried to use the ones that made the cluster
# # in GCP, we use all fields from the artifact, what are your thoughts on this?
# token = data.aws_eks_cluster_auth.auth.token
# }
# }

# Azure providers
# terraform {
# required_version = ">= 1.0"
# required_providers {
# massdriver = {
# source = "massdriver-cloud/massdriver"
# }
# jq = {
# source = "massdriver-cloud/jq"
# }
# azurerm = {
# source = "hashicorp/azurerm"
# }
# azuread = {
# source = "hashicorp/azuread"
# }
# helm = {
# source = "hashicorp/helm"
# }
# }
# }

# locals {
# azure_authentication = module.k8s_application.connections.azure_authentication
# kubernetes_cluster_split_ari = split("/", module.k8s_application.connections.kubernetes_cluster.data.infrastructure.ari)
# kubernetes_cluster_name = local.kubernetes_cluster_split_ari[index(local.kubernetes_cluster_split_ari, "managedClusters") + 1]
# resource_group_name = local.kubernetes_cluster_split_ari[index(local.kubernetes_cluster_split_ari, "resourceGroups") + 1]
# }

# data "azurerm_kubernetes_cluster" "cluster" {
# name = local.kubernetes_cluster_name
# resource_group_name = local.resource_group_name
# }

# provider "azurerm" {
# features {}

# client_id = local.azure_authentication.data.client_id
# tenant_id = local.azure_authentication.data.tenant_id
# client_secret = local.azure_authentication.data.client_secret
# subscription_id = local.azure_authentication.data.subscription_id
# }

# provider "azuread" {
# client_id = local.azure_authentication.data.client_id
# tenant_id = local.azure_authentication.data.tenant_id
# client_secret = local.azure_authentication.data.client_secret
# }

# provider "helm" {
# kubernetes {
# host = data.azurerm_kubernetes_cluster.cluster.kube_config.0.host
# client_certificate = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_admin_config.0.client_certificate)
# client_key = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_admin_config.0.client_key)
# cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config.0.cluster_ca_certificate)
# }
# }

# GCP providers
# terraform {
# required_version = ">= 1.0"
# required_providers {
# massdriver = {
# source = "massdriver-cloud/massdriver"
# }
# jq = {
# source = "massdriver-cloud/jq"
# }
# google = {
# source = "hashicorp/google"
# }
# helm = {
# source = "hashicorp/helm"
# }
# }
# }

# locals {
# gcp_authentication = module.k8s_application.connections.gcp_authentication
# kubernetes_cluster = module.k8s_application.connections.kubernetes_cluster
# gcp_region = split("/", local.kubernetes_cluster.data.infrastructure.grn)[3]
# gcp_project_id = local.gcp_authentication.data.project_id

# k8s_host = local.kubernetes_cluster.data.authentication.cluster.server
# k8s_certificate_authority = base64decode(local.kubernetes_cluster.data.authentication.cluster.certificate-authority-data)
# k8s_token = local.kubernetes_cluster.data.authentication.user.token
# }

# provider "google" {
# project = local.gcp_project_id
# credentials = jsonencode(local.gcp_authentication.data)
# region = local.gcp_region
# }

# provider "helm" {
# kubernetes {
# host = local.k8s_host
# cluster_ca_certificate = local.k8s_certificate_authority
# token = local.k8s_token
# }
# }
terraform {
required_providers {
mdxc = {
source = "massdriver-cloud/mdxc"
}

massdriver = {
source = "massdriver-cloud/massdriver"
}

helm = {
source = "hashicorp/helm"
}
}
}

locals {
# Note: If the field name `kubernetes_cluster` in massdriver.yaml has been changed, this must be updated to match.
kubernetes_cluster = var.kubernetes_cluster
cloud = local.kubernetes_cluster.specs.kubernetes.cloud
}

provider "mdxc" {
azure = local.cloud == "azure" ? {
client_id = var.azure_authentication.data.client_id
tenant_id = var.azure_authentication.data.tenant_id
client_secret = var.azure_authentication.data.client_secret
subscription_id = var.azure_authentication.data.subscription_id
} : null

gcp = local.cloud == "gcp" ? {
project = var.gcp_authentication.data.project_id
credentials = jsonencode(var.gcp_authentication.data)
region = split("/", local.kubernetes_cluster.data.infrastructure.grn)[3]
} : null

aws = local.cloud == "aws" ? {
region = element(split(":", local.kubernetes_cluster.data.infrastructure.arn), 3)
role_arn = var.aws_authentication.data.arn
external_id = var.aws_authentication.data.external_id
} : null
}

provider "helm" {
kubernetes {
host = local.kubernetes_cluster.data.authentication.cluster.server
cluster_ca_certificate = base64decode(local.kubernetes_cluster.data.authentication.cluster.certificate-authority-data)
token = local.kubernetes_cluster.data.authentication.user.token
}
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# TODO: generate a JSON Schema for this, set as params in md yaml, pull fields and add desc.
# TODO: get a simple nginx app working with this.
image:
repository:
tag:

nameOverride: thing

command: []
args: []

Expand Down Expand Up @@ -32,7 +32,6 @@ ingress:
path:

labels: {}

# nodeSelector: {}

# tolerations: []
Expand Down
7 changes: 7 additions & 0 deletions kubernetes-deployment/src/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module "helm" {
source = "github.com/massdriver-cloud/terraform-modules//massdriver-application-helm"
name = var.md_metadata.name_prefix
namespace = var.namespace
chart = "${path.module}/chart"
kubernetes_cluster = var.kubernetes_cluster
}

0 comments on commit 0b46e5e

Please sign in to comment.