Skip to content

Commit

Permalink
Online Boutique's Helm chart (GoogleCloudPlatform#1353)
Browse files Browse the repository at this point in the history
* Create initial Helm chart

* currency and email

* Complete Helm chart for Online Boutique

* cat helm-template.yaml

* Add warning about Helm being in experimental mode

* Use 2022 for Apache license headers

* Link to values.yaml in helm-chart/README.md

* Fix issue with bool in env var

* Fix issue with bool in env var (take 2/2)

* Review naming convention + add externalRedisTlsOrigination

* Fix CI issues

* Fix CI issue with Sidecar

* Add seccompProfile for more security, disable by default

* Helm chart push in release process

* More elegant and consistent way to automate the Helm chart package/push

* Update NOTES.txt

* Update NOTES.txt

* Update NOTES.txt

Co-authored-by: Nim Jayawardena <nimjay@google.com>
  • Loading branch information
Mathieu Benoit and NimJay committed Dec 8, 2022
1 parent dc58fd0 commit 77c520a
Show file tree
Hide file tree
Showing 23 changed files with 2,993 additions and 34 deletions.
68 changes: 68 additions & 0 deletions .github/workflows/helm-chart-ci.yaml
@@ -0,0 +1,68 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: helm-chart-ci
on:
push:
branches:
- main
paths:
- 'helm-chart/**'
- '.github/workflows/helm-chart-ci.yaml'
pull_request:
paths:
- 'helm-chart/**'
- '.github/workflows/helm-chart-ci.yaml'
jobs:
helm-chart-ci:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: helm lint
run: |
cd helm-chart/
helm lint
- name: helm template default
run: |
cd helm-chart/
helm template . > helm-template.yaml
cat helm-template.yaml
- name: kustomize build default
run: |
cd helm-chart/
kustomize create --resources helm-template.yaml
kustomize build .
- name: helm template advanced
run: |
cd helm-chart/
helm template . \
--set images.repository=us-docker.pkg.dev/my-project/containers/onlineboutique \
--set frontend.externalService=false \
--set redis.create=false \
--set cartservice.database.type=spanner \
--set cartservice.database.connectionString=projects/my-project/instances/onlineboutique/databases/carts \
--set serviceAccounts.create=true \
--set authorizationPolicies.create=true \
--set networkPolicies.create=true \
--set sidecars.create=true \
--set frontend.virtualService.create=true \
--set 'serviceAccounts.annotations.iam\.gke\.io/gcp-service-account=spanner-db-user@my-project.iam.gserviceaccount.com' \
--set serviceAccounts.annotationsOnlyForCartservice=true \
-n onlineboutique \
> helm-template.yaml
cat helm-template.yaml
- name: kustomize build advanced
run: |
cd helm-chart/
kustomize build .
33 changes: 33 additions & 0 deletions hack/make-helm-chart.sh
@@ -0,0 +1,33 @@
#!/usr/bin/env bash

# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Packages and pushes Online Boutique's Helm chart in public Artifact Registry.

set -euo pipefail
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

log() { echo "$1" >&2; }

TAG="${TAG:?TAG env variable must be specified}"
HELM_CHART_REPO="us-docker.pkg.dev/online-boutique-ci/charts"

cd helm-chart
sed -i "s/^appVersion:.*/appVersion: \"${TAG}\"/" Chart.yaml
sed -i "s/^version:.*/version: ${TAG:1}/" Chart.yaml
helm package .
helm push onlineboutique-$TAG.tgz oci://$HELM_CHART_REPO

log "Successfully built and pushed the Helm chart."
4 changes: 4 additions & 0 deletions hack/make-release.sh
Expand Up @@ -50,10 +50,14 @@ git pull
# update yaml
"${SCRIPTDIR}"/make-release-artifacts.sh

# build and push images
"${SCRIPTDIR}"/make-helm-chart.sh

# create git release / push to new branch
git checkout -b "release/${TAG}"
git add "${SCRIPTDIR}/../release/"
git add "${SCRIPTDIR}/../kustomize/base/"
git add "${SCRIPTDIR}/../helm-chart/"
git commit --allow-empty -m "Release $TAG"
log "Pushing k8s manifests to release/${TAG}..."
git tag "$TAG"
Expand Down
24 changes: 24 additions & 0 deletions helm-chart/Chart.yaml
@@ -0,0 +1,24 @@
apiVersion: v2
name: onlineboutique
description: A Helm chart for Kubernetes for Online Boutique

# 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.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot 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.4.2

# 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: "v0.4.2"
30 changes: 30 additions & 0 deletions helm-chart/README.md
@@ -0,0 +1,30 @@
# Helm chart for Online Boutique

If you'd like to deploy Online Boutique via its Helm chart, you could leverage the following instructions.

**Warning:** Online Boutique's Helm chart is currently experimental. If you have feedback or run into issues, let us know inside [GitHub Issue #1319](https://github.com/GoogleCloudPlatform/microservices-demo/issues/1319) or by creating a [new GitHub Issue](https://github.com/GoogleCloudPlatform/microservices-demo/issues/new/choose).

Deploy the default setup of Online Boutique:
```sh
helm install onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique
```

Deploy advanced scenario of Online Boutique:
```sh
helm install onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \
--set images.repository=us-docker.pkg.dev/my-project/containers/onlineboutique \
--set frontend.externalService=false \
--set redis.create=false \
--set cartservice.database.type=spanner \
--set cartservice.database.connectionString=projects/my-project/instances/onlineboutique/databases/carts \
--set serviceAccounts.create=true \
--set authorizationPolicies.create=true \
--set networkPolicies.create=true \
--set sidecars.create=true \
--set frontend.virtualService.create=true \
--set 'serviceAccounts.annotations.iam\.gke\.io/gcp-service-account=spanner-db-user@my-project.iam.gserviceaccount.com' \
--set serviceAccounts.annotationsOnlyForCartservice=true \
-n onlineboutique
```

For the full list of configurations, see [values.yaml](./values.yaml).
13 changes: 13 additions & 0 deletions helm-chart/templates/NOTES.txt
@@ -0,0 +1,13 @@
{{- if and .Values.frontend.create .Values.frontend.externalService }}
Note: It may take a few minutes for the LoadBalancer IP to be available.

Watch the status of the frontend IP address with:
kubectl get --namespace {{ .Release.Namespace }} svc -w {{ .Values.frontend.name }}-external

Get the external IP address of the frontend:
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ .Values.frontend.name }}-external --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP
{{- end }}
{{- if .Values.frontend.virtualService.create }}

{{- end }}
184 changes: 184 additions & 0 deletions helm-chart/templates/adservice.yaml
@@ -0,0 +1,184 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

{{- if .Values.adService.create }}
{{- if .Values.serviceAccounts.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.adService.name }}
namespace: {{.Release.Namespace}}
{{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }}
{{- with .Values.serviceAccounts.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
---
{{- end }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
selector:
matchLabels:
app: {{ .Values.adService.name }}
template:
metadata:
labels:
app: {{ .Values.adService.name }}
spec:
{{- if .Values.serviceAccounts.create }}
serviceAccountName: {{ .Values.adService.name }}
{{- else }}
serviceAccountName: default
{{- end }}
terminationGracePeriodSeconds: 5
securityContext:
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
{{- if .Values.seccompProfile.enable }}
seccompProfile:
type: {{ .Values.seccompProfile.type }}
{{- end }}
containers:
- name: server
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
privileged: false
readOnlyRootFilesystem: true
image: {{ .Values.images.repository }}/{{ .Values.adService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }}{{ .Values.images.tagSuffix }}
ports:
- containerPort: 9555
env:
- name: PORT
value: "9555"
resources:
requests:
cpu: 200m
memory: 180Mi
limits:
cpu: 300m
memory: 300Mi
readinessProbe:
initialDelaySeconds: 20
periodSeconds: 15
{{- if .Values.nativeGrpcHealthCheck }}
grpc:
port: 9555
{{- else }}
exec:
command: ["/bin/grpc_health_probe", "-addr=:9555"]
{{- end }}
livenessProbe:
initialDelaySeconds: 20
periodSeconds: 15
{{- if .Values.nativeGrpcHealthCheck }}
grpc:
port: 9555
{{- else }}
exec:
command: ["/bin/grpc_health_probe", "-addr=:9555"]
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
type: ClusterIP
selector:
app: {{ .Values.adService.name }}
ports:
- name: grpc
port: 9555
targetPort: 9555
{{- if .Values.networkPolicies.create }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
podSelector:
matchLabels:
app: {{ .Values.adService.name }}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: {{ .Values.frontend.name }}
ports:
- port: 9555
protocol: TCP
egress:
- {}
{{- end }}
{{- if .Values.sidecars.create }}
---
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
workloadSelector:
labels:
app: {{ .Values.adService.name }}
egress:
- hosts:
- istio-system/*
{{- end }}
{{- if .Values.authorizationPolicies.create }}
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: {{ .Values.adService.name }}
namespace: {{ .Release.Namespace }}
spec:
selector:
matchLabels:
app: {{ .Values.adService.name }}
rules:
- from:
- source:
principals:
{{- if .Values.serviceAccounts.create }}
- cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }}
{{- else }}
- cluster.local/ns/{{ .Release.Namespace }}/sa/default
{{- end }}
to:
- operation:
paths:
- /hipstershop.AdService/GetAds
methods:
- POST
ports:
- "9555"
{{- end }}
{{- end }}

0 comments on commit 77c520a

Please sign in to comment.