Skip to content

Instantly share code, notes, and snippets.

@mohanpedala
Forked from jeroenr/Chart.yaml
Created August 14, 2019 18:33
Show Gist options
  • Save mohanpedala/f2eca7762589c61c8c43a2b298e1b375 to your computer and use it in GitHub Desktop.
Save mohanpedala/f2eca7762589c61c8c43a2b298e1b375 to your computer and use it in GitHub Desktop.
Env specific helm deployment
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "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).
*/}}
{{- define "fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified my-app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "my-app.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s-%s" .Release.Name .Chart.Name .Values.my-app.name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- range $key, $value := .Values.my-app.configs }}
---
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app: {{ template "name" $ }}
chart: {{ $.Chart.Name }}-{{ $.Chart.Version }}
component: "{{ $.Values.my-app.name }}"
heritage: {{ $.Release.Service }}
release: {{ $.Release.Name }}
name: {{ template "my-app.fullname" $ }}-{{ $key }}
data:
{{ toYaml $value | indent 2 }}
{{- end }}
{{- range $key, $value := .Values.my-app.configs }}
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: {{ template "name" $ }}-{{ $key }}
chart: {{ $.Chart.Name }}-{{ $.Chart.Version }}
config: {{ $key }}
component: "{{ $.Values.my-app.name }}"
heritage: {{ $.Release.Service }}
release: {{ $.Release.Name }}
name: {{ template "my-app.fullname" $ }}-{{ $key }}
spec:
strategy:
rollingUpdate:
maxUnavailable: 10%
template:
metadata:
{{- if $.Values.my-app.podAnnotations }}
annotations:
{{ toYaml $.Values.my-app.podAnnotations | indent 8 }}
{{- end }}
labels:
app: {{ template "name" $ }}-{{ $key }}
component: "{{ $.Values.my-app.name }}"
release: {{ $.Release.Name }}
spec:
{{- if $.Values.my-app.nodeSelector }}
nodeSelector:
{{ toYaml $.Values.my-app.nodeSelector | indent 8 }}
{{- end }}
containers:
- name: {{ template "name" $ }}-{{ $.Values.my-app.name }}-{{ $key }}
image: "{{ $.Values.my-app.image.repository }}:{{ $.Values.my-app.image.tag }}"
imagePullPolicy: "{{ $.Values.my-app.image.pullPolicy }}"
resources:
{{ toYaml $.Values.my-app.resources | indent 12 }}
ports:
- containerPort: 8080
env:
- name: CHART_NAME
value: {{ $.Chart.Name }}
- name: ENV_NAME
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: VERSION
value: {{ $.Values.my-app.image.tag }}
envFrom:
- configMapRef:
name: {{ template "my-app.fullname" $ }}-{{ $key }}
{{- end }}
{{- range $key, $value := .Values.my-app.configs }}
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
labels:
app: {{ template "name" $ }}
chart: {{ $.Chart.Name }}-{{ $.Chart.Version }}
component: "{{ $.Values.my-app.name }}"
config: {{ $key }}
heritage: {{ $.Release.Service }}
release: {{ $.Release.Name }}
name: {{ template "my-app.fullname" $ }}-{{ $key }}
spec:
scaleTargetRef:
kind: Deployment
name: {{ template "my-app.fullname" $ }}-{{ $key }}
minReplicas: {{ $.Values.my-app.scaling.minReplicas }}
maxReplicas: {{ $.Values.my-app.scaling.maxReplicas }}
targetCPUUtilizationPercentage: {{ $.Values.my-app.scaling.targetCPU }}
{{- end }}
{{- range $key, $value := .Values.my-app.configs }}
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
{{- if $.Values.my-app.ingress.annotations }}
annotations:
{{ toYaml $.Values.my-app.ingress.annotations | indent 4 }}
{{- end }}
labels:
app: {{ template "name" $ }}
chart: {{ $.Chart.Name }}-{{ $.Chart.Version }}
component: "{{ $.Values.my-app.name }}"
config: {{ $key }}
heritage: {{ $.Release.Service }}
release: {{ $.Release.Name }}
name: {{ template "my-app.fullname" $ }}-{{ $key }}
spec:
rules:
{{- if $.Values.my-app.ingress.host }}
- host: "{{ $.Values.my-app.ingress.host }}"
{{- else }}
- host: "{{ $.Values.my-app.name }}-{{ $.Release.Namespace }}.{{ $.Values.my-app.ingress.DNSWildcardName }}"
{{- end }}
http:
paths:
- path: "{{ $.Values.my-app.ingress.path }}"
backend:
serviceName: {{ template "my-app.fullname" $ }}-{{ $key }}
servicePort: 80
{{- end }}
{{- range $key, $value := .Values.my-app.configs }}
---
apiVersion: v1
kind: Service
metadata:
labels:
app: {{ template "name" $ }}-{{ $key }}
chart: {{ $.Chart.Name }}-{{ $.Chart.Version }}
component: "{{ $.Values.my-app.name }}"
heritage: {{ $.Release.Service }}
release: {{ $.Release.Name }}
name: {{ template "my-app.fullname" $ }}-{{ $key }}
spec:
ports:
- name: my-app
port: 80
protocol: TCP
targetPort: 8080
selector:
app: {{ template "name" $ }}-{{ $key }}
component: "{{ $.Values.my-app.name }}"
release: {{ $.Release.Name }}
type: NodePort
{{- end }}
name: my-app-chart
version: 0.0.1 # Use Jenkinsfile for versioning
description: My App
keywords:
- app
maintainers:
- name: Jeroen Rosenberg
email: [email protected]
engine: gotpl
my-app:
ingress:
annotations:
ingress.kubernetes.io/proxy-body-size: 20m
scaling:
minReplicas: 1
maxReplicas: 1
targetCPU: 80
resources:
limits:
cpu: 1
memory: 1500Mi
requests:
cpu: 800m
memory: 1500Mi
configs:
develop:
SOME_VAR: "dev"
nodeSelector:
cloud.google.com/gke-nodepool: dev-pool
#!groovy
def getGitRev() {
def gitRevWithNewLine = sh script: 'git rev-parse --short HEAD', returnStdout: true
def gitRev = gitRevWithNewLine.trim()
sh "echo Extracted ${gitRev} revision from git"
return gitRev
}
def deployHelmValues(apps, brand, cluster, envName, helmValuesPath, defaultChart) {
node {
checkout scm
def tag = getGitRev()
def appsWithCorrectTags = apps.collectEntries { appName, tagId ->
def imageTag = (tagId == null || tagId.empty) ? tag : tagId
["$appName":imageTag]
}
def firstAppName = apps.keySet()[0]
sh "echo Deploying apps ${appsWithCorrectTags} to ${cluster} cluster for brand $brand"
sh "echo Using Helm config from $helmValuesPath"
def appFlags = appsWithCorrectTags.collect { appName, imageTag ->
"""--set ${appName}.image.tag=\"${imageTag}\" \
--set ${appName}.enabled=true \\"""
}.join("\n")
def chart = "blueprints/${defaultChart}"
stage("deploy") {
withCredentials([string(credentialsId: 'helm_blueprints_repository_url', variable: 'HELM_REPO_URL')]) {
withCredentials([file(credentialsId: "${brand}-gce-service-account", variable: 'FILE')]) {
sh """
export USERNAME= "_json_key"
set +x; export GOOGLE_AUTH_JSON=\"\$(cat $FILE)\"; set -x
export GKE_CLUSTER="${cluster}"
helm upgrade ${envName}-${firstAppName} ${chart} \
--install \
--values ${helmValuesPath} \
--namespace ${envName} \
$appFlags
--set global.image.tag=\"${tag}\"
"""
}
}
}
}
}
def deployAppsByCluster(apps, brand, clusterDevelop, clusterStaging, clusterMaster, chart = 'radar-flow') {
// TODO: standardize
switch(env.BRANCH_NAME) {
case ~/^PR-/:
case "develop":
deployHelmValues(apps, brand, clusterDevelop, "develop", "dev.values.yaml", chart)
break
case ~/^release\/.*$/:
deployHelmValues(apps, brand, clusterStaging, "staging", "staging.values.yaml", chart)
break
case "master":
deployHelmValues(apps, brand, clusterMaster, "master", "prod.values.yaml", chart)
break
default:
try {
timeout(time: 10, unit: 'MINUTES') { //If we don't confirm in 10 minutes we abort
def userInput = input('Let\'s deploy?')
}
deployHelmValues(apps, brand,cluster, "develop", helmValuesBasePath + "develop.yaml", chart)
} catch(err) { // timeout reached
echo("Skipping deployment")
currentBuild.result = 'SUCCESS' // set build to success
}
break
}
}
def deployApps(apps, brand, cluster, chart = 'radar-flow') {
deployAppsByCluster(apps, brand, cluster, cluster, cluster, chart)
}
def deploy(app, brand, cluster, chart = 'radar-flow') {
deployApps(["$app":""], brand, cluster, chart)
}
library 'jenkins-pipelines-lib' // import helm.groovy
sbt.buildAndPush("my-project", promptForRelease=true)
helm.deployAppsByCluster(["my-app":""], "my-project", "my-dev-env", "my-staging-env", "my-project-env", "my-chart-name")
my-app:
ingress:
annotations:
ingress.kubernetes.io/proxy-body-size: 20m
scaling:
minReplicas: 1
maxReplicas: 1
targetCPU: 80
resources:
limits:
cpu: 1
memory: 1500Mi
requests:
cpu: 800m
memory: 1500Mi
configs:
develop:
SOME_VAR: "prod"
nodeSelector:
cloud.google.com/gke-nodepool: prod-pool
my-app:
ingress:
annotations:
ingress.kubernetes.io/proxy-body-size: 20m
scaling:
minReplicas: 1
maxReplicas: 1
targetCPU: 80
resources:
limits:
cpu: 1
memory: 1500Mi
requests:
cpu: 800m
memory: 1500Mi
configs:
develop:
SOME_VAR: "staging"
nodeSelector:
cloud.google.com/gke-nodepool: staging-pool
my-app:
name: my-app
image:
repository: eu.gcr.io/my-project/my-app
tag: ""
pullPolicy: IfNotPresent
ingress:
path: "/"
DNSWildcardName: my-env.my-domain.my-tld
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/proxy-body-size: 20m
nodeSelector: {}
resources:
limits:
cpu: 1
memory: 1000Mi
requests:
cpu: 100m
memory: 1000Mi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment