Skip to content

Commit 11bc0fb

Browse files
authored
Merge pull request #136 from synthesized-io/internal-tls
Enable optional internal TLS
2 parents d38da05 + 974486f commit 11bc0fb

13 files changed

+605
-9
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
{{/*
2+
Envoy sidecar container template
3+
Usage: {{ include "governor.tlsInternal.sidecar" (dict "componentName" "api" "config" .Values.api "tlsInternal" .Values.envoy "hasHttpPort" true "hasGrpcPort" true) }}
4+
*/}}
5+
{{- define "governor.tlsInternal.sidecar" -}}
6+
- name: envoy-sidecar
7+
image: "{{ .tlsInternal.image.repository }}:{{ .tlsInternal.image.tag }}"
8+
imagePullPolicy: {{ .tlsInternal.image.pullPolicy }}
9+
args:
10+
- -c
11+
- /etc/envoy/envoy.yaml
12+
- --log-level
13+
- {{ .tlsInternal.logLevel }}
14+
ports:
15+
{{- if .hasHttpPort }}
16+
- name: https
17+
containerPort: {{ .tlsInternal.ports.secureHttp }}
18+
protocol: TCP
19+
{{- end }}
20+
{{- if .hasGrpcPort }}
21+
- name: grpcs
22+
containerPort: {{ .tlsInternal.ports.secureGrpc }}
23+
protocol: TCP
24+
{{- end }}
25+
- name: admin
26+
containerPort: {{ .tlsInternal.ports.admin }}
27+
protocol: TCP
28+
readinessProbe:
29+
httpGet:
30+
path: /ready
31+
port: {{ .tlsInternal.ports.admin }}
32+
initialDelaySeconds: 5
33+
periodSeconds: 10
34+
livenessProbe:
35+
httpGet:
36+
path: /ready
37+
port: {{ .tlsInternal.ports.admin }}
38+
initialDelaySeconds: 10
39+
periodSeconds: 15
40+
resources:
41+
{{- toYaml .tlsInternal.resources | nindent 4 }}
42+
volumeMounts:
43+
- name: envoy-config
44+
mountPath: /etc/envoy
45+
readOnly: true
46+
- name: tls-certs
47+
mountPath: /etc/envoy/certs
48+
readOnly: true
49+
{{- end }}
50+
51+
{{/*
52+
Envoy init container to wait for certificates
53+
Usage: {{ include "governor.tlsInternal.initContainer" . }}
54+
*/}}
55+
{{- define "governor.tlsInternal.initContainer" -}}
56+
- name: wait-for-certs
57+
image: busybox:1.36
58+
command:
59+
- /bin/sh
60+
- -c
61+
- |
62+
echo "Waiting for TLS certificates..."
63+
while [ ! -f /etc/envoy/certs/tls.crt ] || [ ! -f /etc/envoy/certs/tls.key ]; do
64+
echo "Certificates not ready, waiting..."
65+
sleep 2
66+
done
67+
echo "Certificates are ready!"
68+
volumeMounts:
69+
- name: tls-certs
70+
mountPath: /etc/envoy/certs
71+
readOnly: true
72+
{{- end }}
73+
74+
{{/*
75+
Envoy volumes template
76+
Usage: {{ include "governor.tlsInternal.volumes" (dict "componentName" "api" "config" .Values.api "tlsInternal" .Values.envoy) }}
77+
*/}}
78+
{{- define "governor.tlsInternal.volumes" -}}
79+
- name: envoy-config
80+
configMap:
81+
name: {{ .config.name }}-envoy-config
82+
- name: tls-certs
83+
secret:
84+
secretName: {{ .config.name }}-tls
85+
{{- end }}
86+
87+
{{/*
88+
Envoy HTTP router filter (used in all listeners)
89+
*/}}
90+
{{- define "governor.envoy.httpRouter" -}}
91+
- name: envoy.filters.http.router
92+
typed_config:
93+
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
94+
{{- end }}
95+
96+
{{/*
97+
Envoy downstream TLS context (for inbound TLS termination)
98+
*/}}
99+
{{- define "governor.envoy.downstreamTls" -}}
100+
transport_socket:
101+
name: envoy.transport_sockets.tls
102+
typed_config:
103+
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
104+
common_tls_context:
105+
tls_certificates:
106+
- certificate_chain:
107+
filename: /etc/envoy/certs/tls.crt
108+
private_key:
109+
filename: /etc/envoy/certs/tls.key
110+
{{- end }}
111+
112+
{{/*
113+
Envoy upstream TLS context (for egress with CA validation)
114+
*/}}
115+
{{- define "governor.envoy.upstreamTls" -}}
116+
transport_socket:
117+
name: envoy.transport_sockets.tls
118+
typed_config:
119+
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
120+
common_tls_context:
121+
validation_context:
122+
trusted_ca:
123+
filename: /etc/envoy/certs/ca.crt
124+
{{- end }}
125+
126+
{{/*
127+
Envoy gRPC egress listener to api (shared by front and agent)
128+
*/}}
129+
{{- define "governor.envoy.apiGrpcEgressListener" -}}
130+
- name: api_grpc_egress
131+
address:
132+
socket_address:
133+
address: 127.0.0.1
134+
port_value: {{ .egressGrpcPort }}
135+
filter_chains:
136+
- filters:
137+
- name: envoy.filters.network.http_connection_manager
138+
typed_config:
139+
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
140+
stat_prefix: api_grpc_egress
141+
codec_type: HTTP2
142+
route_config:
143+
name: api_grpc_route
144+
virtual_hosts:
145+
- name: api_grpc_service
146+
domains: ["*"]
147+
routes:
148+
- match:
149+
prefix: "/"
150+
route:
151+
cluster: api_grpcs
152+
http_filters:
153+
{{- include "governor.envoy.httpRouter" . | nindent 14 }}
154+
{{- end }}
155+
156+
{{/*
157+
Envoy api gRPCS upstream cluster (shared by front and agent)
158+
*/}}
159+
{{- define "governor.envoy.apiGrpcsCluster" -}}
160+
- name: api_grpcs
161+
type: STRICT_DNS
162+
connect_timeout: 5s
163+
http2_protocol_options: {}
164+
load_assignment:
165+
cluster_name: api_grpcs
166+
endpoints:
167+
- lb_endpoints:
168+
- endpoint:
169+
address:
170+
socket_address:
171+
address: {{ .apiName }}
172+
port_value: {{ .apiGrpcPort }}
173+
{{- include "governor.envoy.upstreamTls" . | nindent 2 }}
174+
{{- end }}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{{- if .Values.tlsInternal.enabled }}
2+
---
3+
# Certificate for governor-api
4+
apiVersion: cert-manager.io/v1
5+
kind: Certificate
6+
metadata:
7+
name: {{ .Values.api.name }}-cert
8+
labels:
9+
app: {{ .Values.api.name }}
10+
spec:
11+
secretName: {{ .Values.api.name }}-tls
12+
duration: {{ .Values.tlsInternal.certificates.duration }}
13+
renewBefore: {{ .Values.tlsInternal.certificates.renewBefore }}
14+
privateKey:
15+
algorithm: {{ .Values.tlsInternal.certificates.privateKey.algorithm }}
16+
size: {{ .Values.tlsInternal.certificates.privateKey.size }}
17+
usages:
18+
- server auth
19+
- client auth
20+
dnsNames:
21+
- {{ .Values.api.name }}
22+
- {{ .Values.api.name }}.{{ .Release.Namespace }}
23+
- {{ .Values.api.name }}.{{ .Release.Namespace }}.svc
24+
- {{ .Values.api.name }}.{{ .Release.Namespace }}.svc.cluster.local
25+
issuerRef:
26+
name: {{ .Values.tlsInternal.certificates.issuerRef.name }}
27+
kind: {{ .Values.tlsInternal.certificates.issuerRef.kind }}
28+
---
29+
# Certificate for governor-front
30+
apiVersion: cert-manager.io/v1
31+
kind: Certificate
32+
metadata:
33+
name: {{ .Values.front.name }}-cert
34+
labels:
35+
app: {{ .Values.front.name }}
36+
spec:
37+
secretName: {{ .Values.front.name }}-tls
38+
duration: {{ .Values.tlsInternal.certificates.duration }}
39+
renewBefore: {{ .Values.tlsInternal.certificates.renewBefore }}
40+
privateKey:
41+
algorithm: {{ .Values.tlsInternal.certificates.privateKey.algorithm }}
42+
size: {{ .Values.tlsInternal.certificates.privateKey.size }}
43+
usages:
44+
- server auth
45+
- client auth
46+
dnsNames:
47+
- {{ .Values.front.name }}
48+
- {{ .Values.front.name }}.{{ .Release.Namespace }}
49+
- {{ .Values.front.name }}.{{ .Release.Namespace }}.svc
50+
- {{ .Values.front.name }}.{{ .Release.Namespace }}.svc.cluster.local
51+
issuerRef:
52+
name: {{ .Values.tlsInternal.certificates.issuerRef.name }}
53+
kind: {{ .Values.tlsInternal.certificates.issuerRef.kind }}
54+
---
55+
# Certificate for governor-agent
56+
apiVersion: cert-manager.io/v1
57+
kind: Certificate
58+
metadata:
59+
name: {{ .Values.agent.name }}-cert
60+
labels:
61+
app: {{ .Values.agent.name }}
62+
spec:
63+
secretName: {{ .Values.agent.name }}-tls
64+
duration: {{ .Values.tlsInternal.certificates.duration }}
65+
renewBefore: {{ .Values.tlsInternal.certificates.renewBefore }}
66+
privateKey:
67+
algorithm: {{ .Values.tlsInternal.certificates.privateKey.algorithm }}
68+
size: {{ .Values.tlsInternal.certificates.privateKey.size }}
69+
usages:
70+
- client auth
71+
dnsNames:
72+
- {{ .Values.agent.name }}
73+
issuerRef:
74+
name: {{ .Values.tlsInternal.certificates.issuerRef.name }}
75+
kind: {{ .Values.tlsInternal.certificates.issuerRef.kind }}
76+
{{- end }}

charts/governor/templates/configmap-agent.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,18 @@ metadata:
44
name: {{ .Values.agent.name }}-configmap
55
data:
66
{{- if .Values.agent.container.config }}
7+
{{- if .Values.tlsInternal.enabled }}
8+
# Override API connection to use local Envoy egress
9+
AGENT_SERVERHOST: '127.0.0.1'
10+
AGENT_SERVERPORT: '{{ .Values.tlsInternal.ports.egressGrpc }}'
11+
AGENT_USEPLAINTEXT: "true"
12+
# Include other config values except the server connection ones
13+
{{- range $key, $value := .Values.agent.container.config }}
14+
{{- if and (ne $key "AGENT_SERVERHOST") (ne $key "AGENT_SERVERPORT") (ne $key "AGENT_USEPLAINTEXT") }}
15+
{{ $key }}: {{ $value | quote }}
16+
{{- end }}
17+
{{- end }}
18+
{{- else }}
719
{{ toYaml .Values.agent.container.config | indent 2}}
820
{{- end }}
21+
{{- end }}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{{- if .Values.tlsInternal.enabled }}
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: {{ .Values.agent.name }}-envoy-config
6+
labels:
7+
app: {{ .Values.agent.name }}
8+
data:
9+
envoy.yaml: |
10+
admin:
11+
address:
12+
socket_address:
13+
address: 0.0.0.0
14+
port_value: {{ .Values.tlsInternal.ports.admin }}
15+
16+
static_resources:
17+
listeners:
18+
{{- include "governor.envoy.apiGrpcEgressListener" (dict "egressGrpcPort" .Values.tlsInternal.ports.egressGrpc) | nindent 8 }}
19+
20+
clusters:
21+
{{- include "governor.envoy.apiGrpcsCluster" (dict "apiName" .Values.api.name "apiGrpcPort" .Values.api.service.grpcPort) | nindent 8 }}
22+
{{- end }}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
{{- if .Values.tlsInternal.enabled }}
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: {{ .Values.api.name }}-envoy-config
6+
labels:
7+
app: {{ .Values.api.name }}
8+
data:
9+
envoy.yaml: |
10+
admin:
11+
address:
12+
socket_address:
13+
address: 0.0.0.0
14+
port_value: {{ .Values.tlsInternal.ports.admin }}
15+
16+
static_resources:
17+
listeners:
18+
# HTTPS inbound listener (for front -> api HTTP calls)
19+
- name: https_inbound
20+
address:
21+
socket_address:
22+
address: 0.0.0.0
23+
port_value: {{ .Values.tlsInternal.ports.secureHttp }}
24+
filter_chains:
25+
- filters:
26+
- name: envoy.filters.network.http_connection_manager
27+
typed_config:
28+
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
29+
stat_prefix: https_inbound
30+
codec_type: AUTO
31+
route_config:
32+
name: local_route
33+
virtual_hosts:
34+
- name: local_service
35+
domains: ["*"]
36+
routes:
37+
- match:
38+
prefix: "/"
39+
route:
40+
cluster: local_http
41+
http_filters:
42+
{{- include "governor.envoy.httpRouter" . | nindent 22 }}
43+
{{- include "governor.envoy.downstreamTls" . | nindent 14 }}
44+
45+
# gRPCS inbound listener (for agent -> api and front -> api gRPC calls)
46+
- name: grpcs_inbound
47+
address:
48+
socket_address:
49+
address: 0.0.0.0
50+
port_value: {{ .Values.tlsInternal.ports.secureGrpc }}
51+
filter_chains:
52+
- filters:
53+
- name: envoy.filters.network.http_connection_manager
54+
typed_config:
55+
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
56+
stat_prefix: grpcs_inbound
57+
codec_type: HTTP2
58+
route_config:
59+
name: grpc_route
60+
virtual_hosts:
61+
- name: grpc_service
62+
domains: ["*"]
63+
routes:
64+
- match:
65+
prefix: "/"
66+
route:
67+
cluster: local_grpc
68+
http_filters:
69+
{{- include "governor.envoy.httpRouter" . | nindent 22 }}
70+
{{- include "governor.envoy.downstreamTls" . | nindent 14 }}
71+
72+
clusters:
73+
# Local HTTP backend (api container)
74+
- name: local_http
75+
type: STATIC
76+
connect_timeout: 5s
77+
load_assignment:
78+
cluster_name: local_http
79+
endpoints:
80+
- lb_endpoints:
81+
- endpoint:
82+
address:
83+
socket_address:
84+
address: 127.0.0.1
85+
port_value: {{ .Values.api.container.port }}
86+
87+
# Local gRPC backend (api container)
88+
- name: local_grpc
89+
type: STATIC
90+
connect_timeout: 5s
91+
http2_protocol_options: {}
92+
load_assignment:
93+
cluster_name: local_grpc
94+
endpoints:
95+
- lb_endpoints:
96+
- endpoint:
97+
address:
98+
socket_address:
99+
address: 127.0.0.1
100+
port_value: {{ .Values.api.container.grpcPort }}
101+
{{- end }}

0 commit comments

Comments
 (0)