Skip to content

Commit

Permalink
Merge pull request #17 from yoderme/yoderme/helm
Browse files Browse the repository at this point in the history
A Helm chart for a cloudflare tunnel.
  • Loading branch information
nmldiegues authored Feb 15, 2022
2 parents adb44da + 402dd87 commit 509d36c
Show file tree
Hide file tree
Showing 8 changed files with 334 additions and 0 deletions.
23 changes: 23 additions & 0 deletions helm/cloudflare-tunnel/.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/
22 changes: 22 additions & 0 deletions helm/cloudflare-tunnel/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: v2
name: cloudflare-tunnel
description: Creation of a cloudflared deployment - a reverse tunnel for an environment

# 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.
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

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "2022.1.3"

# Let's look professional with a Cloudflare icon.
icon: https://developers.cloudflare.com/cloudflare-one/favicon-32x32.png
51 changes: 51 additions & 0 deletions helm/cloudflare-tunnel/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "cloudflare-tunnel.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 "cloudflare-tunnel.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-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

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

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

{{/*
Selector labels
*/}}
{{- define "cloudflare-tunnel.selectorLabels" -}}
app.kubernetes.io/name: {{ include "cloudflare-tunnel.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
29 changes: 29 additions & 0 deletions helm/cloudflare-tunnel/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This configmap stores the configuration used by cloudflared.
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "cloudflare-tunnel.fullname" . }}
data:
config.yaml: |
# Name of the tunnel you want to run
tunnel: {{ .Values.cloudflare.tunnelName }}
# The location of the secret containing the tunnel credentials
credentials-file: /etc/cloudflared/creds/credentials.json
# General purpose TCP routing for the network
warp-routing:
enabled: {{ .Values.cloudflare.enableWarp }}
# Serves the metrics server under /metrics and the readiness server under /ready
metrics: 0.0.0.0:2000
# Autoupdates applied in a k8s pod will be lost when the pod is removed or restarted, so
# autoupdate doesn't make sense in Kubernetes. However, outside of Kubernetes, we strongly
# recommend using autoupdate.
no-autoupdate: true
# The `ingress` block tells cloudflared which local service to route incoming
# requests to. For more about ingress rules, see
# https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/ingress
ingress:
{{- with .Values.cloudflare.ingress }}
{{- toYaml . | nindent 6 }}
{{- end }}
# This rule matches any traffic which didn't match a previous rule, and responds with HTTP 404.
- service: http_status:404
102 changes: 102 additions & 0 deletions helm/cloudflare-tunnel/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Here we deploy cloudflared images. The tunnel credentials are stored in
# a k8s secret, and the configuration is stored in a k8s configmap.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "cloudflare-tunnel.fullname" . }}
labels:
{{- include "cloudflare-tunnel.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "cloudflare-tunnel.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
# These are here so the deployment rolls when the config or secret change.
checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "cloudflare-tunnel.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "cloudflare-tunnel.fullname" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
args:
- tunnel
# Points cloudflared to the config file, which configures what
# cloudflared will actually do. This file is created by a ConfigMap.
- --config
- /etc/cloudflared/config/config.yaml
- run
livenessProbe:
httpGet:
# Cloudflared has a /ready endpoint which returns 200 if and only if
# it has an active connection to the edge.
path: /ready
port: 2000
failureThreshold: 1
initialDelaySeconds: 10
periodSeconds: 10
volumeMounts:
- name: config
mountPath: /etc/cloudflared/config
readOnly: true
# Each tunnel has an associated "credentials file" which authorizes machines
# to run the tunnel. cloudflared will read this file from its local filesystem,
# and it'll be stored in a k8s secret.
- name: creds
mountPath: /etc/cloudflared/creds
readOnly: true
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: creds
secret:
secretName: {{ include "cloudflare-tunnel.fullname" . }}
- name: config
configMap:
name: {{ include "cloudflare-tunnel.fullname" . }}
items:
- key: config.yaml
path: config.yaml
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
affinity:
{{- with .Values.affinity }}
{{- toYaml . | nindent 8 }}
{{- else }}
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 10
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchExpressions:
{{- range $k, $v := include "cloudflare-tunnel.selectorLabels" . | fromYaml }}
- key: {{ $k }}
operator: In
values:
- {{ $v }}
{{- end }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
16 changes: 16 additions & 0 deletions helm/cloudflare-tunnel/templates/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This credentials secret allows cloudflared to authenticate itself
# to the Cloudflare infrastructure.
apiVersion: v1
kind: Secret
metadata:
name: {{ include "cloudflare-tunnel.fullname" . }}
labels:
{{- include "cloudflare-tunnel.labels" . | nindent 4 }}
stringData:
credentials.json: |-
{
"AccountTag": {{ .Values.cloudflare.account | quote }},
"TunnelID": {{ .Values.cloudflare.tunnelId | quote }},
"TunnelName": {{ .Values.cloudflare.tunnelName | quote }},
"TunnelSecret": {{ .Values.cloudflare.secret | quote }}
}
12 changes: 12 additions & 0 deletions helm/cloudflare-tunnel/templates/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Here we create a service account with no privileges to run the
# deployment - just in case the default service account is different.
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "cloudflare-tunnel.fullname" . }}
labels:
{{- include "cloudflare-tunnel.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
79 changes: 79 additions & 0 deletions helm/cloudflare-tunnel/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Default values for cloudflare-tunnel.

# Cloudflare parameters.
cloudflare:
# Your Cloudflare account number.
account: ""
# The name of the tunnel this instance will serve
tunnelName: ""
# The ID of the above tunnel.
tunnelId: ""
# The secret for the tunnel.
secret: ""
# If true, turn on WARP routing for TCP
enableWarp: false
# Define ingress rules for the tunnel. See
# https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/configuration-file/ingress
ingress: []
# The first rule proxies traffic to the httpbin sample service named web-server at port 80
# - hostname: tunnel.example.com
# service: http://web-service:80
# This rule sends traffic to the built-in hello-world HTTP server. This can help debug connectivity
# issues. If hello.example.com resolves and tunnel.example.com does not, then the problem is
# in the connection from cloudflared to your local service, not from the internet to cloudflared.
# - hostname: hello.example.com
# service: hello_world

image:
repository: cloudflare/cloudflared
pullPolicy: IfNotPresent
# If supplied, this overrides "appVersion"
tag: ""

replicaCount: 2

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

serviceAccount:
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""

podAnnotations: {}

# Security items common to everything in the pod. Here we require that it
# does not run as the user defined in the image, literally named "nonroot".
podSecurityContext:
runAsNonRoot: true
runAsUser: 65532

# Security items for one container. We lock it down.
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true

resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi

nodeSelector: {}

tolerations: []

# Default affinity is to spread out over nodes; use this to override.
affinity: {}

0 comments on commit 509d36c

Please sign in to comment.