mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 00:37:45 +00:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31d1086345 | ||
|
|
b737543c13 | ||
|
|
8e150ee0d7 | ||
|
|
117a2a886d | ||
|
|
79b41dfbf5 | ||
|
|
55562f9d83 | ||
|
|
e0a636f183 | ||
|
|
1fa74214cf | ||
|
|
e5851cac57 | ||
|
|
4a26662b92 | ||
|
|
6bc6888ffc | ||
|
|
dab1f305e1 | ||
|
|
fbe79dd0af | ||
|
|
6d6829b149 | ||
|
|
971a3fa280 | ||
|
|
7632344cd1 | ||
|
|
42067748ad | ||
|
|
340c3484e5 | ||
|
|
250238c286 | ||
|
|
a223e2b426 | ||
|
|
63a7da02e7 | ||
|
|
569f827e30 | ||
|
|
4a656db2ec | ||
|
|
77b0933961 | ||
|
|
3b796cfbbd | ||
|
|
8a7a010b94 | ||
|
|
2454f6e9ee | ||
|
|
63d00bfddf | ||
|
|
f34da6c24e | ||
|
|
1d98069b73 | ||
|
|
e956b64d04 | ||
|
|
054d33b498 | ||
|
|
f2f75a4e00 | ||
|
|
a0cf73faf9 | ||
|
|
d74655c632 | ||
|
|
b8019429b8 | ||
|
|
9c08214118 | ||
|
|
f58d791e03 | ||
|
|
836033e16a | ||
|
|
77279d9baf | ||
|
|
bf19aee1a7 | ||
|
|
4de88b3155 |
14
.cspell.json
14
.cspell.json
@@ -17,8 +17,11 @@
|
||||
"buildplan",
|
||||
"cainjector",
|
||||
"CAROOT",
|
||||
"certificaterequests",
|
||||
"certificatesigningrequests",
|
||||
"clsx",
|
||||
"clusterissuer",
|
||||
"clusterissuers",
|
||||
"clusterrole",
|
||||
"clusterrolebinding",
|
||||
"configmap",
|
||||
@@ -45,6 +48,7 @@
|
||||
"flushcache",
|
||||
"gatewayclasses",
|
||||
"gendoc",
|
||||
"ggnpl",
|
||||
"ghaction",
|
||||
"gitops",
|
||||
"godoc",
|
||||
@@ -57,10 +61,12 @@
|
||||
"holoslogger",
|
||||
"horizontalpodautoscaler",
|
||||
"httpbin",
|
||||
"httproute",
|
||||
"httproutes",
|
||||
"Infima",
|
||||
"isatty",
|
||||
"istiod",
|
||||
"jbrx",
|
||||
"jetstack",
|
||||
"Jsonnet",
|
||||
"killall",
|
||||
@@ -71,12 +77,15 @@
|
||||
"Kustomizations",
|
||||
"kustomize",
|
||||
"ldflags",
|
||||
"leaderelection",
|
||||
"libnss",
|
||||
"loadbalancer",
|
||||
"mattn",
|
||||
"mccutchen",
|
||||
"mindmap",
|
||||
"mktemp",
|
||||
"msqbn",
|
||||
"mtls",
|
||||
"Multicluster",
|
||||
"mutatingwebhookconfiguration",
|
||||
"mxcl",
|
||||
@@ -86,6 +95,7 @@
|
||||
"orgid",
|
||||
"otelconnect",
|
||||
"Parentspanid",
|
||||
"pcjc",
|
||||
"peerauthentications",
|
||||
"pflag",
|
||||
"pipefail",
|
||||
@@ -100,12 +110,15 @@
|
||||
"proxyconfigs",
|
||||
"Pulumi",
|
||||
"putenv",
|
||||
"qjbp",
|
||||
"quickstart",
|
||||
"referencegrant",
|
||||
"referencegrants",
|
||||
"requestauthentications",
|
||||
"retryable",
|
||||
"rolebinding",
|
||||
"ropc",
|
||||
"seccomp",
|
||||
"SECRETKEY",
|
||||
"secretstores",
|
||||
"serverlb",
|
||||
@@ -117,6 +130,7 @@
|
||||
"startupapicheck",
|
||||
"stefanprodan",
|
||||
"structpb",
|
||||
"subjectaccessreviews",
|
||||
"svclb",
|
||||
"systemconnect",
|
||||
"tablewriter",
|
||||
|
||||
@@ -11,18 +11,29 @@ import (
|
||||
|
||||
//go:generate ../../../hack/gendoc
|
||||
|
||||
// Component represents the fields common the different kinds of component. All
|
||||
// components have a name, support mixing in resources, and produce a BuildPlan.
|
||||
type ComponentFields struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
// Resources are kubernetes api objects to mix into the output.
|
||||
Resources map[string]any
|
||||
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
|
||||
ArgoConfig ArgoConfig
|
||||
// BuildPlan represents the derived BuildPlan for the Holos cli to render.
|
||||
BuildPlan core.BuildPlan
|
||||
}
|
||||
|
||||
// Helm provides a BuildPlan via the Output field which contains one HelmChart
|
||||
// from package core. Useful as a convenience wrapper to render a HelmChart
|
||||
// with optional mix-in resources and Kustomization post-processing.
|
||||
type Helm struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
ComponentFields `json:",inline"`
|
||||
|
||||
// Version represents the chart version.
|
||||
Version string
|
||||
// Namespace represents the helm namespace option when rendering the chart.
|
||||
Namespace string
|
||||
// Resources are kubernetes api objects to mix into the output.
|
||||
Resources map[string]any
|
||||
|
||||
// Repo represents the chart repository
|
||||
Repo struct {
|
||||
@@ -57,27 +68,23 @@ type Helm struct {
|
||||
// KustomizeResources represents additional resources files to include in the
|
||||
// kustomize resources list.
|
||||
KustomizeResources map[string]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
|
||||
ArgoConfig ArgoConfig
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
|
||||
// Resources represents the default schema for a Kubernetes API object resource.
|
||||
// For example, a Service, Namespace or Deployment. The top level key is the
|
||||
// kind of resource so default behavior and strict schema enforcement may be
|
||||
// enforced for the kind. The second level keys are an arbitrary internal
|
||||
// label, which serves as the default value for the resource metadata name
|
||||
// field, but may differ for situations where the same resource kind and name
|
||||
// are managed in different namespaces.
|
||||
//
|
||||
// Refer to [definitions.cue] for the CUE schema definition as an example to
|
||||
// build on when defining your own Components.
|
||||
//
|
||||
// [definitions.cue]: https://github.com/holos-run/holos/blob/main/internal/generate/platforms/cue.mod/pkg/github.com/holos-run/holos/api/schema/v1alpha3/definitions.cue#L9
|
||||
// type Resources map[string]map[string]any
|
||||
// Kustomize provides a BuildPlan via the Output field which contains one
|
||||
// KustomizeBuild from package core.
|
||||
type Kustomize struct {
|
||||
ComponentFields `json:",inline"`
|
||||
// Kustomization represents the kustomize build plan for holos to render.
|
||||
Kustomization core.KustomizeBuild
|
||||
}
|
||||
|
||||
// Kubernetes provides a BuildPlan via the Output field which contains inline
|
||||
// API Objects provided directly from CUE.
|
||||
type Kubernetes struct {
|
||||
ComponentFields `json:",inline"`
|
||||
// Objects represents the kubernetes api objects for the Component.
|
||||
Objects core.KubernetesObjects
|
||||
}
|
||||
|
||||
// ArgoConfig represents the ArgoCD GitOps configuration for a Component.
|
||||
// Useful to define once at the root of the Platform configuration and reuse
|
||||
@@ -99,6 +106,8 @@ type ArgoConfig struct {
|
||||
// Application.spec.source.targetRevision field. Defaults to the branch named
|
||||
// main.
|
||||
TargetRevision string `cue:"string | *\"main\""`
|
||||
// AppProject represents the ArgoCD Project to associate the Application with.
|
||||
AppProject string `cue:"string | *\"default\""`
|
||||
}
|
||||
|
||||
// Cluster represents a cluster managed by the Platform.
|
||||
@@ -147,29 +156,8 @@ type Platform struct {
|
||||
// Output represents the core Platform spec for the holos cli to iterate over
|
||||
// and render each listed Component, injecting the Model.
|
||||
Output core.Platform
|
||||
}
|
||||
|
||||
// Kustomize provides a BuildPlan via the Output field which contains one
|
||||
// KustomizeBuild from package core.
|
||||
type Kustomize struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
|
||||
// Kustomization represents the kustomize build plan for holos to render.
|
||||
Kustomization core.KustomizeBuild
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
|
||||
// Kubernetes provides a BuildPlan via the Output field which contains inline
|
||||
// API Objects provided directly from CUE.
|
||||
type Kubernetes struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
// Resources represents the kubernetes api objects for the Component.
|
||||
Resources map[string]any
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
// Domain represents the primary domain the Platform operates in. This field
|
||||
// is intended as a sensible default for component authors to reference and
|
||||
// platform operators to define.
|
||||
Domain string `cue:"string | *\"holos.localhost\""`
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ Package v1alpha3 contains CUE definitions intended as convenience wrappers aroun
|
||||
|
||||
- [type ArgoConfig](<#ArgoConfig>)
|
||||
- [type Cluster](<#Cluster>)
|
||||
- [type ComponentFields](<#ComponentFields>)
|
||||
- [type Fleet](<#Fleet>)
|
||||
- [type Helm](<#Helm>)
|
||||
- [type Kubernetes](<#Kubernetes>)
|
||||
@@ -43,6 +44,8 @@ type ArgoConfig struct {
|
||||
// Application.spec.source.targetRevision field. Defaults to the branch named
|
||||
// main.
|
||||
TargetRevision string `cue:"string | *\"main\""`
|
||||
// AppProject represents the ArgoCD Project to associate the Application with.
|
||||
AppProject string `cue:"string | *\"default\""`
|
||||
}
|
||||
```
|
||||
|
||||
@@ -62,6 +65,24 @@ type Cluster struct {
|
||||
}
|
||||
```
|
||||
|
||||
<a name="ComponentFields"></a>
|
||||
## type ComponentFields {#ComponentFields}
|
||||
|
||||
Component represents the fields common the different kinds of component. All components have a name, support mixing in resources, and produce a BuildPlan.
|
||||
|
||||
```go
|
||||
type ComponentFields struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
// Resources are kubernetes api objects to mix into the output.
|
||||
Resources map[string]any
|
||||
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
|
||||
ArgoConfig ArgoConfig
|
||||
// BuildPlan represents the derived BuildPlan for the Holos cli to render.
|
||||
BuildPlan core.BuildPlan
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Fleet"></a>
|
||||
## type Fleet {#Fleet}
|
||||
|
||||
@@ -82,14 +103,12 @@ Helm provides a BuildPlan via the Output field which contains one HelmChart from
|
||||
|
||||
```go
|
||||
type Helm struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
ComponentFields `json:",inline"`
|
||||
|
||||
// Version represents the chart version.
|
||||
Version string
|
||||
// Namespace represents the helm namespace option when rendering the chart.
|
||||
Namespace string
|
||||
// Resources are kubernetes api objects to mix into the output.
|
||||
Resources map[string]any
|
||||
|
||||
// Repo represents the chart repository
|
||||
Repo struct {
|
||||
@@ -124,12 +143,6 @@ type Helm struct {
|
||||
// KustomizeResources represents additional resources files to include in the
|
||||
// kustomize resources list.
|
||||
KustomizeResources map[string]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// ArgoConfig represents the ArgoCD GitOps configuration for this Component.
|
||||
ArgoConfig ArgoConfig
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
```
|
||||
|
||||
@@ -140,13 +153,9 @@ Kubernetes provides a BuildPlan via the Output field which contains inline API O
|
||||
|
||||
```go
|
||||
type Kubernetes struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
// Resources represents the kubernetes api objects for the Component.
|
||||
Resources map[string]any
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
ComponentFields `json:",inline"`
|
||||
// Objects represents the kubernetes api objects for the Component.
|
||||
Objects core.KubernetesObjects
|
||||
}
|
||||
```
|
||||
|
||||
@@ -157,14 +166,9 @@ Kustomize provides a BuildPlan via the Output field which contains one Kustomize
|
||||
|
||||
```go
|
||||
type Kustomize struct {
|
||||
// Name represents the Component name.
|
||||
Name string
|
||||
|
||||
ComponentFields `json:",inline"`
|
||||
// Kustomization represents the kustomize build plan for holos to render.
|
||||
Kustomization core.KustomizeBuild
|
||||
|
||||
// Output represents the derived BuildPlan for the Holos cli to render.
|
||||
Output core.BuildPlan
|
||||
}
|
||||
```
|
||||
|
||||
@@ -185,6 +189,10 @@ type Platform struct {
|
||||
// Output represents the core Platform spec for the holos cli to iterate over
|
||||
// and render each listed Component, injecting the Model.
|
||||
Output core.Platform
|
||||
// Domain represents the primary domain the Platform operates in. This field
|
||||
// is intended as a sensible default for component authors to reference and
|
||||
// platform operators to define.
|
||||
Domain string `cue:"string | *\"holos.localhost\""`
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
1862
doc/md/archive/guides/expose-a-service.mdx
Normal file
1862
doc/md/archive/guides/expose-a-service.mdx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,799 +0,0 @@
|
||||
---
|
||||
description: Use Holos to expose a Service with the Gateway API.
|
||||
slug: /guides/expose-a-service
|
||||
sidebar_position: 200
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Expose a Service
|
||||
|
||||
In this guide, you'll learn how to expose a service with Holos using the Gateway
|
||||
API.
|
||||
|
||||
The [Concepts](/docs/concepts) page defines capitalized terms such as Platform
|
||||
and Component.
|
||||
|
||||
## What you'll need {#requirements}
|
||||
|
||||
You'll need the following tools installed to complete this guide.
|
||||
|
||||
1. [holos](/docs/install) - to build the Platform.
|
||||
2. [helm](https://helm.sh/docs/intro/install/) - to render Helm Components.
|
||||
3. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to render Kustomize Components.
|
||||
|
||||
Optionally, if you'd like to apply the rendered manifests to a real Cluster,
|
||||
first complete the [localhost Guide](../local-cluster).
|
||||
|
||||
## Create a Git Repository
|
||||
|
||||
Start by initializing an empty Git repository. Holos operates on local files
|
||||
stored in a Git repository.
|
||||
|
||||
<Tabs groupId="init">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
mkdir expose-a-service
|
||||
cd expose-a-service
|
||||
git init
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
Initialized empty Git repository in /expose-a-service/.git/
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This guide assumes you will run commands from the root directory of the Git
|
||||
repository unless stated otherwise.
|
||||
|
||||
## Generate the Platform {#Generate-Platform}
|
||||
|
||||
Start by generating a platform with one workload Cluster. The `guide` Platform
|
||||
is intended as a starting point for all of our guides.
|
||||
|
||||
<Tabs groupId="generate-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate platform guide
|
||||
holos generate component workload-cluster
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Commit the generated platform config to the repository.
|
||||
|
||||
<Tabs groupId="commit-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos generate platform guide - $(holos --version)"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
[main (root-commit) 0b17b7f] holos generate platform guide - 0.93.3
|
||||
213 files changed, 72349 insertions(+)
|
||||
...
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Gateway API
|
||||
|
||||
The Gateway API is an official Kubernetes project focused on L4 and L7 routing .
|
||||
You'll use the custom resources defined by the Gateway API to expose the httpbin
|
||||
service outside of the cluster. The Kubernetes Gateway API does not come
|
||||
installed by default on most Kubernetes clusters, so we need to manage the
|
||||
custom resource definitions (CRDs).
|
||||
|
||||
Run the following command to generate a Component to manage the Gateway API.
|
||||
|
||||
<Tabs groupId="gen-gateway-api">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component gateway-api
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The command generates two main configuration files, one at the leaf, and another
|
||||
at the root of the tree. At the leaf, the config produces a Kustomize build
|
||||
plan for Holos to render. At the root, the config adds the Component to all
|
||||
Clusters in the Platform.
|
||||
|
||||
Notice the `kustomization.yaml` file at the leaf. This is an unmodified
|
||||
upstream copy of the standard way to install the Gateway API.
|
||||
|
||||
<Tabs groupId="gateway-api-files">
|
||||
<TabItem value="components/gateway-api/gateway-api.cue" label="Leaf">
|
||||
`components/gateway-api/gateway-api.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a kubectl kustomize build plan.
|
||||
(#Kustomize & {Name: "gateway-api"}).Output
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="kustomization.yaml" label="kustomization.yaml">
|
||||
`components/gateway-api/kustomization.yaml`
|
||||
```yaml showLineNumbers
|
||||
resources:
|
||||
- standard/gateway.networking.k8s.io_gatewayclasses.yaml
|
||||
- standard/gateway.networking.k8s.io_gateways.yaml
|
||||
- standard/gateway.networking.k8s.io_grpcroutes.yaml
|
||||
- standard/gateway.networking.k8s.io_httproutes.yaml
|
||||
- standard/gateway.networking.k8s.io_referencegrants.yaml
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="gateway-api.gen.cue" label="Root">
|
||||
`gateway-api.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Manage on every Cluster in the Platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/gateway-api": {
|
||||
path: "components/gateway-api"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Render the Platform to render the Component for the workload clusters.
|
||||
|
||||
<Tabs groupId="render-platform-gateway">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
rendered components/gateway-api for cluster workload in 279.312292ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
This example is equivalent to running `kubectl kustomize
|
||||
./components/gateway-api` and saving the output to a file. Holos simplifies
|
||||
this task and makes it consistent with Helm and other tools.
|
||||
:::
|
||||
|
||||
Add and commit the Component and rendered Platform.
|
||||
|
||||
<Tabs groupId="commit-gateway-api">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "add gateway-api component"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
[main 88575a5] add gateway-api component
|
||||
9 files changed, 26907 insertions(+)
|
||||
create mode 100644 components/gateway-api/gateway-api.cue
|
||||
create mode 100644 components/gateway-api/kustomization.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_gatewayclasses.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_gateways.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_grpcroutes.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_httproutes.yaml
|
||||
create mode 100644 components/gateway-api/standard/gateway.networking.k8s.io_referencegrants.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/gateway-api/gateway-api.gen.yaml
|
||||
create mode 100644 gateway-api.gen.cue
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Optionally apply the rendered component to your cluster.
|
||||
|
||||
<Tabs groupId="apply-gateway-api">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/gateway-api
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Namespaces
|
||||
|
||||
We often need to manage namespaces prior to workloads being deployed. This is
|
||||
necessary because a namespace is a security boundary. Holos makes it easier,
|
||||
safer, and more consistent to manage service accounts, role bindings, and
|
||||
secrets prior to deploying workloads into a namespace.
|
||||
|
||||
We'll see how this works with the namespaces component, which offers a mechanism
|
||||
for other components to register their namespaces. The namespaces component
|
||||
initializes each registered namespace, optionally mixing in resources
|
||||
consistently.
|
||||
|
||||
Run the following command to generate the namespaces component.
|
||||
|
||||
<Tabs groupId="gen-namespaces">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component namespaces
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The command generates two main configuration files like we've seen with other
|
||||
components. One file at the leaf, and another at the root. The leaf uses a
|
||||
Kubernetes build plan to produce resources directly from CUE.
|
||||
|
||||
<Tabs groupId="namespaces-files">
|
||||
<TabItem value="components/namespaces/namespaces.cue" label="Leaf">
|
||||
`components/namespaces/namespaces.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
let Objects = {
|
||||
Name: "namespaces"
|
||||
// highlight-next-line
|
||||
Resources: Namespace: #Namespaces
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).Output
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="namespaces.gen.cue" label="Root">
|
||||
`namespaces.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
import corev1 "k8s.io/api/core/v1"
|
||||
|
||||
// #Namespaces defines all managed namespaces in the Platform.
|
||||
// Holos adopts the sig-multicluster position of namespace sameness.
|
||||
#Namespaces: {
|
||||
// Validate against v1 of the kubernetes core api
|
||||
// highlight-next-line
|
||||
[Name=string]: corev1.#Namespace & {
|
||||
metadata: name: Name
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the Component on every Cluster in the Platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/namespaces": {
|
||||
path: "components/namespaces"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Notice the highlighted line in the leaf file. Resources are managed directly in
|
||||
CUE at the leaf using the Kubernetes component. This is the same mechanism used
|
||||
to mix-in resources to Helm and Kustomize components. The leaf refers to
|
||||
`#Namespaces` defined at the root. At the root `#Namespaces` enforces a
|
||||
constraint: each Namespace must conform to the `k8s.io/api/core/v1`
|
||||
specification.
|
||||
|
||||
:::important
|
||||
We've covered three kinds of components so far. The [Quickstart] guide
|
||||
introduced Helm. We've used Kustomize and Kubernetes in this guide.
|
||||
|
||||
Holos offers a consistent way to manage these different kinds of packaging
|
||||
safely and easily.
|
||||
:::
|
||||
|
||||
- At the **leaf** Holos tailors the component to your platform, mixing
|
||||
in resources and customizing the rendered output.
|
||||
- At the **root** Holos integrates a component with the rest of your platform.
|
||||
|
||||
You'll see this pattern again and again as you build your platform.
|
||||
|
||||
Render the platform to render the component for the workload clusters.
|
||||
|
||||
<Tabs groupId="render-platform-gateway">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
rendered components/namespaces for cluster workload in 72.675292ms
|
||||
rendered components/gateway-api for cluster workload in 259.174583ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Add and commit the configuration and rendered manifests.
|
||||
|
||||
<Tabs groupId="commit-gateway-api">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "add namespaces component"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
[main 1bf0d61] add namespaces component
|
||||
3 files changed, 30 insertions(+)
|
||||
create mode 100644 components/namespaces/namespaces.cue
|
||||
create mode 100644 deploy/clusters/workload/components/namespaces/namespaces.gen.yaml
|
||||
create mode 100644 namespaces.gen.cue
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
`#Namespaces` is currently empty, so the rendered output of
|
||||
`namespaces.gen.yaml` is also empty.
|
||||
|
||||
:::tip
|
||||
Namespaces will be automatically managed as we add more components to the
|
||||
platform over time.
|
||||
:::
|
||||
|
||||
## Istio
|
||||
|
||||
We'll manage Istio to implement the Gateway API so we can expose the httpbin
|
||||
service outside of the cluster.
|
||||
|
||||
Run the following command to generate the istio components.
|
||||
|
||||
<Tabs groupId="gen-istio">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component istio
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::important
|
||||
Mix in the `istio-k3d` component if you're applying the rendered manifests to
|
||||
k3d as described in our [Local Cluster] guide.
|
||||
:::
|
||||
|
||||
Skip this step if you aren't using k3d. Istio needs to be configured to refer
|
||||
to the nonstandard cni configuration paths k3d uses.
|
||||
|
||||
<Tabs groupId="gen-istio-k3d">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component istio-k3d
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="file" label="istio-k3d.gen.cue">
|
||||
Holos makes it easier and safer to mix-in this additional configuration at the root.
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// If you are using k3d with the default Flannel CNI, you must append some
|
||||
// values to your installation command, as k3d uses nonstandard locations for
|
||||
// CNI configuration and binaries.
|
||||
//
|
||||
// See https://istio.io/latest/docs/ambient/install/platform-prerequisites/#k3d
|
||||
#Istio: Values: cni: {
|
||||
cniConfDir: "/var/lib/rancher/k3s/agent/etc/cni/net.d"
|
||||
cniBinDir: "/bin"
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Consistent with the other components we've seen, the istio components define
|
||||
configuration at the root and leafs of the tree. Unlike previous components
|
||||
we've generated, this command generated multiple components to manage Istio.
|
||||
|
||||
<Tabs groupId="tree-istio">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree components/istio
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
components/istio
|
||||
├── base
|
||||
│ ├── istio-base.cue
|
||||
│ └── values.gen.cue
|
||||
├── cni
|
||||
│ ├── cni.cue
|
||||
│ └── values.gen.cue
|
||||
├── gateway
|
||||
│ ├── gateway.cue
|
||||
│ └── values.gen.cue
|
||||
├── istiod
|
||||
│ ├── istiod.cue
|
||||
│ └── values.gen.cue
|
||||
└── ztunnel
|
||||
├── values.gen.cue
|
||||
└── ztunnel.cue
|
||||
|
||||
6 directories, 10 files
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
These components share the configuration defined at the root in `istio.gen.cue`.
|
||||
|
||||
Let's review how Holos makes it safer and easier to share Helm values defined at
|
||||
the root with the istiod and cni components defined at the leaf.
|
||||
|
||||
1. istiod and cni use version `"1.23.1"` and namespace `"istio-system"` defined at
|
||||
the root.
|
||||
2. The Helm value to configure ambient (sidecar-less) mode is defined once at
|
||||
the root.
|
||||
3. The root adds a constraint to fail validation if the istio system namespace
|
||||
is not `"istio-system"`. Future upgrades are safer with this constraint, if the
|
||||
upstream vendor changes the default in the future the component will fail
|
||||
validation.
|
||||
4. The root registers two Namespaces, `"istio-system"` and `"istio-ingress"`.
|
||||
5. The root manages the components on all workload clusters in the platform.
|
||||
|
||||
<Tabs groupId="istio-files">
|
||||
<TabItem value="istiod.cue" label="istiod">
|
||||
Leaf `components/istio/istiod/istiod.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istiod"
|
||||
// highlight-next-line
|
||||
Version: #Istio.Version
|
||||
// highlight-next-line
|
||||
Namespace: #Istio.System.Namespace
|
||||
|
||||
Chart: chart: name: "istiod"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
// highlight-next-line
|
||||
Values: #Istio.Values
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cni.cue" label="cni">
|
||||
Leaf `components/istio/cni/cni.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-cni"
|
||||
// highlight-next-line
|
||||
Version: #Istio.Version
|
||||
// highlight-next-line
|
||||
Namespace: #Istio.System.Namespace
|
||||
|
||||
Chart: chart: name: "cni"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
// highlight-next-line
|
||||
Values: #Istio.Values
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="istio.gen.cue" label="Root">
|
||||
Root `istio.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
#Istio: {
|
||||
// highlight-next-line
|
||||
Version: "1.23.1"
|
||||
// highlight-next-line
|
||||
System: Namespace: "istio-system"
|
||||
Gateway: Namespace: "istio-ingress"
|
||||
|
||||
// Constrain Helm values for safer, easier upgrades and consistency across
|
||||
// platform components.
|
||||
// highlight-next-line
|
||||
Values: global: istioNamespace: System.Namespace
|
||||
|
||||
// Configure ambient mode
|
||||
// highlight-next-line
|
||||
Values: profile: "ambient"
|
||||
}
|
||||
|
||||
// Register the Namespaces
|
||||
#Namespaces: (#Istio.System.Namespace): _
|
||||
#Namespaces: (#Istio.Gateway.Namespace): _
|
||||
|
||||
// Manage istio on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: {
|
||||
"\(Cluster.name)/istio-base": {
|
||||
path: "components/istio/base"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istiod": {
|
||||
path: "components/istio/istiod"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-cni": {
|
||||
path: "components/istio/cni"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-ztunnel": {
|
||||
path: "components/istio/ztunnel"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-gateway": {
|
||||
path: "components/istio/gateway"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
Many software projects managed by Holos are organized into a collection of
|
||||
components working together, for example to safely manage custom resource
|
||||
definitions, secrets, and policy separately from the workloads that rely on
|
||||
them.
|
||||
:::
|
||||
|
||||
Render the platform to render the istio components for the workload clusters.
|
||||
|
||||
<Tabs groupId="render-platform-istio">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
rendered components/namespaces for cluster workload in 85.490833ms
|
||||
rendered components/istio/ztunnel for cluster workload in 111.784667ms
|
||||
rendered components/istio/cni for cluster workload in 112.362417ms
|
||||
rendered components/istio/base for cluster workload in 113.058ms
|
||||
rendered components/istio/gateway for cluster workload in 119.018208ms
|
||||
rendered components/istio/istiod for cluster workload in 127.736334ms
|
||||
rendered components/gateway-api for cluster workload in 181.922333ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Add and commit the configuration and rendered manifests.
|
||||
|
||||
<Tabs groupId="commit-istio">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "add istio"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
[main aca8ff6] add istio
|
||||
18 files changed, 18955 insertions(+)
|
||||
create mode 100644 components/istio/base/istio-base.cue
|
||||
create mode 100644 components/istio/base/values.gen.cue
|
||||
create mode 100644 components/istio/cni/cni.cue
|
||||
create mode 100644 components/istio/cni/values.gen.cue
|
||||
create mode 100644 components/istio/gateway/gateway.cue
|
||||
create mode 100644 components/istio/gateway/values.gen.cue
|
||||
create mode 100644 components/istio/istiod/istiod.cue
|
||||
create mode 100644 components/istio/istiod/values.gen.cue
|
||||
create mode 100644 components/istio/ztunnel/values.gen.cue
|
||||
create mode 100644 components/istio/ztunnel/ztunnel.cue
|
||||
create mode 100644 deploy/clusters/workload/components/istio-base/istio-base.gen.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/istio-cni/istio-cni.gen.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/istio-gateway/istio-gateway.gen.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/istio-ztunnel/istio-ztunnel.gen.yaml
|
||||
create mode 100644 deploy/clusters/workload/components/istiod/istiod.gen.yaml
|
||||
create mode 100644 istio-k3d.gen.cue
|
||||
create mode 100644 istio.gen.cue
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Optionally apply the rendered component to your cluster.
|
||||
|
||||
<Tabs groupId="apply-istio-namespaces">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/namespaces
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
namespace/istio-ingress serverside-applied
|
||||
namespace/istio-system serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istio-base">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-base
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
customresourcedefinition.apiextensions.k8s.io/wasmplugins.extensions.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/destinationrules.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/envoyfilters.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/gateways.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/proxyconfigs.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/serviceentries.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/sidecars.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/virtualservices.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/workloadentries.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/workloadgroups.networking.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/authorizationpolicies.security.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/peerauthentications.security.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/requestauthentications.security.istio.io serverside-applied
|
||||
customresourcedefinition.apiextensions.k8s.io/telemetries.telemetry.istio.io serverside-applied
|
||||
serviceaccount/istio-reader-service-account serverside-applied
|
||||
validatingwebhookconfiguration.admissionregistration.k8s.io/istiod-default-validator serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istiod">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istiod
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
poddisruptionbudget.policy/istiod serverside-applied
|
||||
serviceaccount/istiod serverside-applied
|
||||
configmap/istio serverside-applied
|
||||
configmap/istio-sidecar-injector serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istiod-clusterrole-istio-system serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istiod-gateway-controller-istio-system serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-reader-clusterrole-istio-system serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istiod-clusterrole-istio-system serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istiod-gateway-controller-istio-system serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istio-reader-clusterrole-istio-system serverside-applied
|
||||
role.rbac.authorization.k8s.io/istiod serverside-applied
|
||||
rolebinding.rbac.authorization.k8s.io/istiod serverside-applied
|
||||
service/istiod serverside-applied
|
||||
deployment.apps/istiod serverside-applied
|
||||
horizontalpodautoscaler.autoscaling/istiod serverside-applied
|
||||
mutatingwebhookconfiguration.admissionregistration.k8s.io/istio-sidecar-injector serverside-applied
|
||||
validatingwebhookconfiguration.admissionregistration.k8s.io/istio-validator-istio-system serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istio-cni">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-cni
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
serviceaccount/istio-cni serverside-applied
|
||||
configmap/istio-cni-config serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-cni serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-cni-repair-role serverside-applied
|
||||
clusterrole.rbac.authorization.k8s.io/istio-cni-ambient serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istio-cni serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istio-cni-repair-rolebinding serverside-applied
|
||||
clusterrolebinding.rbac.authorization.k8s.io/istio-cni-ambient serverside-applied
|
||||
daemonset.apps/istio-cni-node serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istio-ztunnel">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-ztunnel
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
serviceaccount/ztunnel serverside-applied
|
||||
daemonset.apps/ztunnel serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Tabs groupId="apply-istio-gateway">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f deploy/clusters/workload/components/istio-gateway
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
serviceaccount/gateway serverside-applied
|
||||
role.rbac.authorization.k8s.io/gateway serverside-applied
|
||||
rolebinding.rbac.authorization.k8s.io/gateway serverside-applied
|
||||
service/gateway serverside-applied
|
||||
deployment.apps/gateway serverside-applied
|
||||
horizontalpodautoscaler.autoscaling/gateway serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Make sure all pod containers become ready.
|
||||
|
||||
<Tabs groupId="apply-istio-ready">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl get pods -A
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
NAMESPACE NAME READY STATUS RESTARTS AGE
|
||||
istio-ingress gateway-6748c5f547-s46pj 1/1 Running 0 26s
|
||||
istio-system istio-cni-node-852nr 1/1 Running 0 2m9s
|
||||
istio-system istiod-5b4d8d4c77-t694z 1/1 Running 0 3m15s
|
||||
istio-system ztunnel-msqbn 1/1 Running 0 63s
|
||||
kube-system coredns-576bfc4dc7-2g4k9 1/1 Running 0 113m
|
||||
kube-system local-path-provisioner-6795b5f9d8-wsz8p 1/1 Running 0 113m
|
||||
kube-system metrics-server-557ff575fb-fctr7 1/1 Running 0 113m
|
||||
kube-system svclb-gateway-5d311af0-fp5mk 3/3 Running 0 26s
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Once all pods are ready, we're ready to manage httpbin so we can route http
|
||||
traffic to it.
|
||||
|
||||
## httpbin
|
||||
|
||||
[Quickstart]: /docs/quickstart
|
||||
[Local Cluster]: /docs/guides/local-cluster
|
||||
@@ -88,7 +88,7 @@ Finally, add your trusted certificate authority.
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f "$(mkcert -CAROOT)/namespace.yaml"
|
||||
kubectl apply --server-side=true -f "$(mkcert -CAROOT)/local-ca.yaml"
|
||||
kubectl apply --server-side=true -n cert-manager -f "$(mkcert -CAROOT)/local-ca.yaml"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
|
||||
106
doc/md/guides/manage-a-project.mdx
Normal file
106
doc/md/guides/manage-a-project.mdx
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
description: Self service platform resource management for project teams.
|
||||
slug: /guides/manage-a-project
|
||||
sidebar_position: 200
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Manage a Project
|
||||
|
||||
In this guide we'll explore how Holos easily, safely, and consistently manages
|
||||
platform resources for teams to develop the projects they're working on.
|
||||
|
||||
Intended Audience: Platform Engineers and Software Engineers.
|
||||
|
||||
Goal is to demonstrate how the platform team can consistently, easily, and
|
||||
safely provide platform resources to software engineers.
|
||||
|
||||
Assumption is software engineers have a container they want to deploy onto the
|
||||
platform and make accessible. We'll use httpbin as a stand-in for the dev
|
||||
team's container.
|
||||
|
||||
Project is roughly equivalent to Dev Team for the purpose of this guide, but in
|
||||
practice multiple teams work on a given project over the lifetime of the
|
||||
project, so we structure the files into projects instead of teams.
|
||||
|
||||
## What you'll need {#requirements}
|
||||
|
||||
You'll need the following tools installed to complete this guide.
|
||||
|
||||
1. [holos](/docs/install) - to build the Platform.
|
||||
2. [helm](https://helm.sh/docs/intro/install/) - to render Helm Components.
|
||||
3. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to render Kustomize Components.
|
||||
|
||||
If you'd like to apply the manifests we render in this guide complete the
|
||||
following optional, but recommended, steps.
|
||||
|
||||
a. Complete the [Local Cluster] guide to set up a local cluster to work with.
|
||||
b. You'll need a GitHub account to fork the repository associated with this
|
||||
guide.
|
||||
|
||||
## Fork the Guide Repository
|
||||
|
||||
<Tabs groupId="fork">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This guide assumes you will run commands from the root directory of this
|
||||
repository unless stated otherwise.
|
||||
|
||||
[Quickstart]: /docs/quickstart
|
||||
[Local Cluster]: /docs/guides/local-cluster
|
||||
|
||||
## Render the Platform
|
||||
|
||||
So we can build the basic platform. Don't dwell on the platform bits.
|
||||
|
||||
## Apply the Manifests
|
||||
|
||||
Deploy ArgoCD, but not any of the Application resources.
|
||||
|
||||
## Browse to ArgoCD
|
||||
|
||||
Note there is nothing here yet.
|
||||
|
||||
## Switch to your Fork
|
||||
|
||||
Note all of the Applications change consistently.
|
||||
|
||||
## Apply the Applications
|
||||
|
||||
Note how ArgoCD takes over management, no longer need to k apply.
|
||||
|
||||
## Create a Project
|
||||
|
||||
Project is a conceptual, not technical, thing in Holos. Mainly about how components are laid out in the filesystem tree.
|
||||
|
||||
We use a schematic built into holos as an example, the platform team could use the same or provide a similar template and instructions for development teams to self-serve.
|
||||
|
||||
## Render the Platform
|
||||
|
||||
Notice:
|
||||
|
||||
1. Project is registered with the platform at the root.
|
||||
2. HTTPRoute and Namespace resources are added close to the root in `projects`
|
||||
3. Deployment and Service resources are added at the leaf in `projects/httpbin/backend`
|
||||
|
||||
## Update the image tag
|
||||
|
||||
Add a basic schematic to demonstrate this. May need to add two new flags for image url and image tag to the generate subcommand, but should just be two new fields on the struct.
|
||||
|
||||
## Dive Deeper
|
||||
|
||||
Set the stage for constraints. Ideas: Limit what resources can be added,
|
||||
namespaces can be operated in, enforce labels, etc...
|
||||
|
||||
Simple, consistent, easy constraints.
|
||||
@@ -263,7 +263,7 @@ following contents:
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
RepoURL: "https://example.com/holos-quickstart.git"
|
||||
RepoURL: "https://github.com/holos-run/holos-quickstart-guide"
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
*/
|
||||
|
||||
/* Enable wrapping by default for mobile */
|
||||
pre code {
|
||||
/* pre code {
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
} */
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubectl kustomize build plan.
|
||||
(#Kustomize & {Name: "{{ .Name }}"}).Output
|
||||
(#Kustomize & {Name: "{{ .Name }}"}).BuildPlan
|
||||
|
||||
@@ -18,4 +18,4 @@ let Objects = {
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).Output
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
@@ -8,4 +8,4 @@ let Objects = {
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).Output
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
@@ -17,4 +17,4 @@ let Chart = {
|
||||
}
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
@@ -12,4 +12,4 @@ let Chart = {
|
||||
}
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package holos
|
||||
|
||||
// Manage the Component on every Cluster in the Platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/app-projects": {
|
||||
path: "projects/platform/components/app-projects"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
import ap "argoproj.io/appproject/v1alpha1"
|
||||
|
||||
// Registration point for AppProjects
|
||||
#AppProjects: [Name=string]: ap.#AppProject & {
|
||||
metadata: name: Name
|
||||
metadata: namespace: #ArgoCD.Namespace
|
||||
spec: description: string | *"Holos managed AppProject"
|
||||
spec: clusterResourceWhitelist: [{group: "*", kind: "*"}]
|
||||
spec: destinations: [{namespace: "*", server: "*"}]
|
||||
spec: sourceRepos: ["*"]
|
||||
}
|
||||
|
||||
// Define at least the platform project. Other components can register projects
|
||||
// the same way from the root of the configuration.
|
||||
#AppProjects: platform: _
|
||||
@@ -0,0 +1,9 @@
|
||||
package holos
|
||||
|
||||
let Objects = {
|
||||
Name: "app-projects"
|
||||
Resources: AppProject: #AppProjects
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "app-projects",
|
||||
"short": "#AppProjects registration point",
|
||||
"long": "Manage ArgoCD AppProject resources centrally."
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package holos
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
RepoURL: "https://github.com/holos-run/holos-manage-a-project-guide"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#ArgoConfig: AppProject: #AppProjects.platform.metadata.name
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "argocd-config-manage-a-project-guide",
|
||||
"short": "generate applications for the manage-a-project guide",
|
||||
"long": "https://github.com/holos-run/holos-manage-a-project-guide"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
// Manage the Component on every Cluster in the Platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/argocd-crds": {
|
||||
path: "projects/platform/components/argocd/crds"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/argocd": {
|
||||
path: "projects/platform/components/argocd/argocd"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package holos
|
||||
|
||||
// #ArgoCD represents platform wide configuration
|
||||
#ArgoCD: {
|
||||
Version: "2.12.3"
|
||||
Namespace: "argocd"
|
||||
}
|
||||
|
||||
// Register namespaces
|
||||
#Namespaces: (#ArgoCD.Namespace): _
|
||||
|
||||
// Register the HTTPRoute to the backend Service
|
||||
#HTTPRoutes: argocd: _backendRefs: "argocd-server": namespace: #ArgoCD.Namespace
|
||||
@@ -0,0 +1,60 @@
|
||||
package holos
|
||||
|
||||
import "strings"
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
let Chart = {
|
||||
Name: "argocd"
|
||||
Namespace: #ArgoCD.Namespace
|
||||
Version: "7.5.2"
|
||||
|
||||
Repo: name: "argocd"
|
||||
Repo: url: "https://argoproj.github.io/argo-helm"
|
||||
|
||||
Chart: chart: name: "argo-cd"
|
||||
Chart: chart: release: Name
|
||||
// Upstream uses a Kubernetes Job to create the argocd-redis Secret. Enable
|
||||
// hooks to enable the Job.
|
||||
Chart: enableHooks: true
|
||||
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
// Grant the Gateway namespace the ability to refer to the backend service
|
||||
// from HTTPRoute resources.
|
||||
Resources: ReferenceGrant: (#Istio.Gateway.Namespace): #ReferenceGrant
|
||||
|
||||
EnableKustomizePostProcessor: true
|
||||
// Force all resources into the component namespace, some resources in the
|
||||
// helm chart may not specify the namespace so they may get mis-applied
|
||||
// depending on the kubectl (client-go) context.
|
||||
KustomizeFiles: "kustomization.yaml": namespace: Namespace
|
||||
|
||||
Values: #Values & {
|
||||
kubeVersionOverride: "1.29.0"
|
||||
// handled in the argo-crds component
|
||||
crds: install: false
|
||||
// Configure the same fqdn the HTTPRoute is configured with.
|
||||
global: domain: #HTTPRoutes.argocd.spec.hostnames[0]
|
||||
dex: enabled: false
|
||||
// the platform handles mutual tls to the backend
|
||||
configs: params: "server.insecure": true
|
||||
|
||||
configs: cm: {
|
||||
"admin.enabled": false
|
||||
"oidc.config": "{}"
|
||||
"users.anonymous.enabled": "true"
|
||||
}
|
||||
|
||||
// Refer to https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/
|
||||
let Policy = [
|
||||
"g, argocd-view, role:readonly",
|
||||
"g, prod-cluster-view, role:readonly",
|
||||
"g, prod-cluster-edit, role:readonly",
|
||||
"g, prod-cluster-admin, role:admin",
|
||||
]
|
||||
|
||||
configs: rbac: "policy.csv": strings.Join(Policy, "\n")
|
||||
configs: rbac: "policy.default": "role:admin"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
ks "sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
(#Kubernetes & {Name: "argocd-crds"}).BuildPlan
|
||||
|
||||
// Holos stages BuildPlan resources as an intermediate step of the rendering
|
||||
// pipeline. The purpose is to provide the resources to kustomize for
|
||||
// post-processing.
|
||||
let BuildPlanResources = "build-plan-resources.yaml"
|
||||
|
||||
let Kustomization = ks.#Kustomization & {
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1"
|
||||
kind: "Kustomization"
|
||||
resources: [
|
||||
// Kustomize the intermediate build plan resources.
|
||||
BuildPlanResources,
|
||||
// Mix-in external resources.
|
||||
"https://raw.githubusercontent.com/argoproj/argo-cd/v\(#ArgoCD.Version)/manifests/crds/application-crd.yaml",
|
||||
"https://raw.githubusercontent.com/argoproj/argo-cd/v\(#ArgoCD.Version)/manifests/crds/applicationset-crd.yaml",
|
||||
"https://raw.githubusercontent.com/argoproj/argo-cd/v\(#ArgoCD.Version)/manifests/crds/appproject-crd.yaml",
|
||||
// This method also works, but takes about 5 seconds longer each build.
|
||||
// "https://github.com/argoproj/argo-cd//manifests/crds/?ref=v\(#ArgoCD.Version)",
|
||||
]
|
||||
}
|
||||
|
||||
// Generate a kustomization.yaml directly from CUE so we can provide the correct
|
||||
// version.
|
||||
spec: components: kubernetesObjectsList: [{
|
||||
// intermediate build plan resources to kustomize. Necessary to activate the
|
||||
// kustomization post-rendering step in holos.
|
||||
kustomize: resourcesFile: BuildPlanResources
|
||||
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(Kustomization)
|
||||
}]
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "argocd",
|
||||
"short": "declaritive gitops for kubernetes",
|
||||
"long": "Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes."
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package holos
|
||||
|
||||
// Manage on workload clusters only
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
// Owned by the security team
|
||||
#Platform: Components: "\(Cluster.name)/bank-secrets": {
|
||||
path: "projects/bank-of-holos/security/components/bank-secrets"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
|
||||
// Owned by the frontend team
|
||||
#Platform: Components: "\(Cluster.name)/bank-frontend": {
|
||||
path: "projects/bank-of-holos/frontend/components/bank-frontend"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
|
||||
// Owned by the backend team
|
||||
#Platform: Components: "\(Cluster.name)/bank-backend-config": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-backend-config"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-accounts-db": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-accounts-db"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-userservice": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-userservice"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
|
||||
#Platform: Components: "\(Cluster.name)/bank-ledger-db": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-ledger-db"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-ledger-writer": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-ledger-writer"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-balance-reader": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-balance-reader"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-transaction-history": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-transaction-history"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/bank-contacts": {
|
||||
path: "projects/bank-of-holos/backend/components/bank-contacts"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package holos
|
||||
|
||||
// Platform wide definitions
|
||||
#BankOfHolos: {
|
||||
Name: "bank-of-holos"
|
||||
Frontend: Namespace: "bank-frontend"
|
||||
Backend: Namespace: "bank-backend"
|
||||
Security: Namespace: "bank-security"
|
||||
|
||||
// Resources to manage in each of the namespaces.
|
||||
Resources: #Resources
|
||||
}
|
||||
|
||||
// Register namespaces
|
||||
#Namespaces: (#BankOfHolos.Frontend.Namespace): _
|
||||
#Namespaces: (#BankOfHolos.Backend.Namespace): _
|
||||
#Namespaces: (#BankOfHolos.Security.Namespace): _
|
||||
|
||||
// Register projects
|
||||
#AppProjects: "bank-frontend": _
|
||||
#AppProjects: "bank-backend": _
|
||||
#AppProjects: "bank-security": _
|
||||
|
||||
// Register HTTPRoutes.
|
||||
// bank.example.com routes to Service frontend in the bank-frontend namespace.
|
||||
#HTTPRoutes: bank: _backendRefs: frontend: namespace: #BankOfHolos.Frontend.Namespace
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#ArgoConfig: AppProject: #AppProjects["bank-backend"].metadata.name
|
||||
@@ -0,0 +1,122 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "accounts"
|
||||
tier: "db"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-accounts-db"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/accounts-db.yaml
|
||||
Resources: {
|
||||
ConfigMap: "accounts-db-config": {
|
||||
apiVersion: "v1"
|
||||
data: {
|
||||
ACCOUNTS_DB_URI: "postgresql://accounts-admin:accounts-pwd@accounts-db:5432/accounts-db"
|
||||
POSTGRES_DB: "accounts-db"
|
||||
POSTGRES_PASSWORD: "accounts-pwd"
|
||||
POSTGRES_USER: "accounts-admin"
|
||||
}
|
||||
kind: "ConfigMap"
|
||||
metadata: {
|
||||
labels: {
|
||||
app: "accounts-db"
|
||||
CommonLabels
|
||||
}
|
||||
name: "accounts-db-config"
|
||||
}
|
||||
}
|
||||
|
||||
Service: "accounts-db": {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
name: "accounts-db"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "tcp"
|
||||
port: 5432
|
||||
protocol: "TCP"
|
||||
targetPort: 5432
|
||||
}]
|
||||
selector: {
|
||||
app: "accounts-db"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
StatefulSet: "accounts-db": {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "StatefulSet"
|
||||
metadata: {
|
||||
name: "accounts-db"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
replicas: 1
|
||||
selector: matchLabels: {
|
||||
app: "accounts-db"
|
||||
CommonLabels
|
||||
}
|
||||
serviceName: "accounts-db"
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "accounts-db"
|
||||
CommonLabels
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "accounts-db-config"
|
||||
}, {
|
||||
configMapRef: name: "demo-data-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/accounts-db:v0.6.5@sha256:abb955756a82b115e0fd9c5fa1527ae1a744b398b357fd6d7a26348feccad181"
|
||||
name: "accounts-db"
|
||||
ports: [{containerPort: 5432}]
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
memory: "512Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
}
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/var/lib/postgresql/data"
|
||||
name: "postgresdb"
|
||||
subPath: "postgres"
|
||||
}]
|
||||
}]
|
||||
serviceAccount: BankName
|
||||
serviceAccountName: BankName
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "postgresdb"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-backend-config"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/userservice.yaml
|
||||
Resources: {
|
||||
// Allow HTTPRoutes in the ingress gateway namespace to reference Services
|
||||
// in this namespace.
|
||||
ReferenceGrant: grant: #ReferenceGrant & {
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
|
||||
// Include shared resources
|
||||
#BankOfHolos.Resources
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "ledger"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-balance-reader"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
Service: balancereader: {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
name: "balancereader"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
}]
|
||||
selector: {
|
||||
app: "balancereader"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: balancereader: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
metadata: {
|
||||
name: "balancereader"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "balancereader"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "balancereader"
|
||||
CommonLabels
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "ENABLE_METRICS"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "POLL_MS"
|
||||
value: "100"
|
||||
}, {
|
||||
name: "CACHE_SIZE"
|
||||
value: "1000000"
|
||||
}, {
|
||||
name: "JVM_OPTS"
|
||||
value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms256m -Xmx512m"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "NAMESPACE"
|
||||
valueFrom: fieldRef: fieldPath: "metadata.namespace"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "ledger-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/balancereader:v0.6.5@sha256:de01f16554ae2d0b49ac85116e6307da8c0f8a35f50a0cf25e1e4a4fe18dca83"
|
||||
livenessProbe: {
|
||||
httpGet: {
|
||||
path: "/healthy"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 120
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
name: "balancereader"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "500m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "512Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "256Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
startupProbe: {
|
||||
failureThreshold: 30
|
||||
httpGet: {
|
||||
path: "/healthy"
|
||||
port: 8080
|
||||
}
|
||||
periodSeconds: 10
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
securityContext: {
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "accounts"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-contacts"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
Service: contacts: {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: name: "contacts"
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
}]
|
||||
selector: {
|
||||
app: "contacts"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: contacts: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
metadata: name: "contacts"
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "contacts"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: "contacts"
|
||||
CommonLabels
|
||||
}
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "accounts-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/contacts:v0.6.5@sha256:e451dcac7d34a7bde979c7f02d4c7ebd83a77aff373e1131ce3a2bba2f7fdc1a"
|
||||
name: "contacts"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
"ephemeral-storage": "0.25Gi"
|
||||
memory: "128Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
"ephemeral-storage": "0.25Gi"
|
||||
memory: "64Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
securityContext: {
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "ledger"
|
||||
tier: "db"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-ledger-db"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
ConfigMap: "ledger-db-config": {
|
||||
apiVersion: "v1"
|
||||
metadata: {
|
||||
name: "ledger-db-config"
|
||||
labels: {
|
||||
app: "ledger-db"
|
||||
CommonLabels
|
||||
}
|
||||
}
|
||||
data: {
|
||||
POSTGRES_DB: "postgresdb"
|
||||
POSTGRES_PASSWORD: "password"
|
||||
POSTGRES_USER: "admin"
|
||||
SPRING_DATASOURCE_PASSWORD: "password"
|
||||
SPRING_DATASOURCE_URL: "jdbc:postgresql://ledger-db:5432/postgresdb"
|
||||
SPRING_DATASOURCE_USERNAME: "admin"
|
||||
}
|
||||
}
|
||||
|
||||
Service: "ledger-db": {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
name: "ledger-db"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "tcp"
|
||||
port: 5432
|
||||
targetPort: 5432
|
||||
}]
|
||||
selector: {
|
||||
app: "ledger-db"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
StatefulSet: "ledger-db": {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "StatefulSet"
|
||||
metadata: {
|
||||
name: "ledger-db"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
replicas: 1
|
||||
selector: matchLabels: {
|
||||
app: "ledger-db"
|
||||
CommonLabels
|
||||
}
|
||||
serviceName: "ledger-db"
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "ledger-db"
|
||||
CommonLabels
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "ledger-db-config"
|
||||
}, {
|
||||
configMapRef: name: "demo-data-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/ledger-db:v0.6.5@sha256:cc4fd25f301ab6d46b1312244d6931babc4c6cb66c5cb6d31d4a1adfa318a321"
|
||||
name: "postgres"
|
||||
ports: [{containerPort: 5432}]
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
memory: "1Gi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "512Mi"
|
||||
}
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/var/lib/postgresql/data"
|
||||
name: "postgresdb"
|
||||
subPath: "postgres"
|
||||
}]
|
||||
}]
|
||||
serviceAccountName: BankName
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "postgresdb"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "ledger"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-ledger-writer"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
Service: ledgerwriter: {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
name: "ledgerwriter"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
}]
|
||||
selector: {
|
||||
app: "ledgerwriter"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: ledgerwriter: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
metadata: {
|
||||
name: "ledgerwriter"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "ledgerwriter"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: "ledgerwriter"
|
||||
CommonLabels
|
||||
}
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "ENABLE_METRICS"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "JVM_OPTS"
|
||||
value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms256m -Xmx512m"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "NAMESPACE"
|
||||
valueFrom: fieldRef: fieldPath: "metadata.namespace"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "service-api-config"
|
||||
}, {
|
||||
configMapRef: name: "ledger-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/ledgerwriter:v0.6.5@sha256:5b66d6888b87993c8ebe260fe33005c4e4bc2bdae4b5682874e1a078d37ff3b2"
|
||||
name: "ledgerwriter"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "500m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "512Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "256Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
startupProbe: {
|
||||
failureThreshold: 30
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
periodSeconds: 10
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
securityContext: {
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "ledger"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-transaction-history"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [_]: metadata: labels: CommonLabels
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests
|
||||
Resources: {
|
||||
Service: transactionhistory: {
|
||||
apiVersion: "v1"
|
||||
kind: "Service"
|
||||
metadata: {
|
||||
labels: CommonLabels
|
||||
name: "transactionhistory"
|
||||
}
|
||||
spec: {
|
||||
ports: [{
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
}]
|
||||
selector: {
|
||||
app: "transactionhistory"
|
||||
CommonLabels
|
||||
}
|
||||
type: "ClusterIP"
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: transactionhistory: {
|
||||
apiVersion: "apps/v1"
|
||||
kind: "Deployment"
|
||||
metadata: {
|
||||
name: "transactionhistory"
|
||||
labels: CommonLabels
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "transactionhistory"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: "transactionhistory"
|
||||
CommonLabels
|
||||
}
|
||||
}
|
||||
spec: {
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "ENABLE_METRICS"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "POLL_MS"
|
||||
value: "100"
|
||||
}, {
|
||||
name: "CACHE_SIZE"
|
||||
value: "1000"
|
||||
}, {
|
||||
name: "CACHE_MINUTES"
|
||||
value: "60"
|
||||
}, {
|
||||
name: "HISTORY_LIMIT"
|
||||
value: "100"
|
||||
}, {
|
||||
name: "JVM_OPTS"
|
||||
value: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms256m -Xmx512m"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "NAMESPACE"
|
||||
valueFrom: fieldRef: fieldPath: "metadata.namespace"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "ledger-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/transactionhistory:v0.6.5@sha256:54a2b0866df44a50832e71b130f3e069fe8bbce71309fb6cf390b19f64d92c09"
|
||||
livenessProbe: {
|
||||
httpGet: {
|
||||
path: "/healthy"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 120
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
name: "transactionhistory"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "500m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "512Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
"ephemeral-storage": "0.5Gi"
|
||||
memory: "256Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
startupProbe: {
|
||||
failureThreshold: 30
|
||||
httpGet: {
|
||||
path: "/healthy"
|
||||
port: 8080
|
||||
}
|
||||
periodSeconds: 10
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
securityContext: {
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
let CommonLabels = {
|
||||
application: BankName
|
||||
environment: "development"
|
||||
team: "accounts"
|
||||
tier: "backend"
|
||||
}
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-userservice"
|
||||
Namespace: #BankOfHolos.Backend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/userservice.yaml
|
||||
Resources: {
|
||||
Service: userservice: {
|
||||
metadata: name: "userservice"
|
||||
metadata: labels: CommonLabels
|
||||
spec: {
|
||||
selector: {
|
||||
app: "userservice"
|
||||
CommonLabels
|
||||
}
|
||||
_ports: http: {
|
||||
name: "http"
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
protocol: "TCP"
|
||||
}
|
||||
ports: [for x in _ports {x}]
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: userservice: {
|
||||
metadata: name: "userservice"
|
||||
metadata: labels: CommonLabels
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "userservice"
|
||||
CommonLabels
|
||||
}
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "userservice"
|
||||
CommonLabels
|
||||
}
|
||||
spec: {
|
||||
serviceAccountName: BankName
|
||||
terminationGracePeriodSeconds: 5
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "TOKEN_EXPIRY_SECONDS"
|
||||
value: "3600"
|
||||
}, {
|
||||
name: "PRIV_KEY_PATH"
|
||||
value: "/tmp/.ssh/privatekey"
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "accounts-db-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/userservice:v0.6.5@sha256:f91e0e5bd6cdb16f6b867b2e3e874b23dd01f11592de006776f1dfb136702941"
|
||||
name: "userservice"
|
||||
ports: [{
|
||||
containerPort: 8080
|
||||
name: "http-server"
|
||||
}]
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "500m"
|
||||
"ephemeral-storage": "0.25Gi"
|
||||
memory: "256Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "260m"
|
||||
"ephemeral-storage": "0.25Gi"
|
||||
memory: "128Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "keys"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
volumes: [{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
}, {
|
||||
name: "keys"
|
||||
secret: {
|
||||
secretName: "jwt-key"
|
||||
items: [
|
||||
{
|
||||
key: "jwtRS256.key"
|
||||
path: "privatekey"
|
||||
},
|
||||
{
|
||||
key: "jwtRS256.key.pub"
|
||||
path: "publickey"
|
||||
},
|
||||
]
|
||||
}
|
||||
}]
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
core "k8s.io/api/core/v1"
|
||||
es "external-secrets.io/externalsecret/v1beta1"
|
||||
ss "external-secrets.io/secretstore/v1beta1"
|
||||
)
|
||||
|
||||
let BankName = #BankOfHolos.Name
|
||||
|
||||
#BankOfHolos: {
|
||||
// Resources to make available in each of the project namespaces.
|
||||
Resources: {
|
||||
ServiceAccount: (BankName): core.#ServiceAccount & {
|
||||
apiVersion: "v1"
|
||||
kind: "ServiceAccount"
|
||||
metadata: name: BankName
|
||||
}
|
||||
|
||||
// SecretStore to fetch secrets owned by the security team
|
||||
SecretStore: (BankName): ss.#SecretStore & {
|
||||
metadata: name: #BankOfHolos.Security.Namespace
|
||||
spec: provider: {
|
||||
kubernetes: {
|
||||
remoteNamespace: #BankOfHolos.Security.Namespace
|
||||
auth: serviceAccount: name: ServiceAccount[BankName].metadata.name
|
||||
server: {
|
||||
url: "https://kubernetes.default.svc"
|
||||
caProvider: {
|
||||
type: "ConfigMap"
|
||||
name: "kube-root-ca.crt"
|
||||
key: "ca.crt"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We do not check the private key into version control.
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/tree/v0.6.5/extras/jwt
|
||||
ExternalSecret: "jwt-key": es.#ExternalSecret & {
|
||||
metadata: name: "jwt-key"
|
||||
spec: {
|
||||
target: name: metadata.name
|
||||
dataFrom: [{extract: {key: metadata.name}}]
|
||||
refreshInterval: "5s"
|
||||
secretStoreRef: kind: "SecretStore"
|
||||
secretStoreRef: name: SecretStore[BankName].metadata.name
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/config.yaml
|
||||
ConfigMap: "environment-config": core.#ConfigMap & {
|
||||
apiVersion: "v1"
|
||||
kind: "ConfigMap"
|
||||
metadata: name: "environment-config"
|
||||
data: {
|
||||
LOCAL_ROUTING_NUM: "883745000"
|
||||
PUB_KEY_PATH: "/tmp/.ssh/publickey"
|
||||
}
|
||||
}
|
||||
|
||||
ConfigMap: "service-api-config": core.#ConfigMap & {
|
||||
apiVersion: "v1"
|
||||
kind: "ConfigMap"
|
||||
metadata: name: "service-api-config"
|
||||
data: {
|
||||
TRANSACTIONS_API_ADDR: "ledgerwriter.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
BALANCES_API_ADDR: "balancereader.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
HISTORY_API_ADDR: "transactionhistory.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
CONTACTS_API_ADDR: "contacts.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
USERSERVICE_API_ADDR: "userservice.\(#BankOfHolos.Backend.Namespace).svc:8080"
|
||||
}
|
||||
}
|
||||
|
||||
ConfigMap: "demo-data-config": core.#ConfigMap & {
|
||||
apiVersion: "v1"
|
||||
kind: "ConfigMap"
|
||||
metadata: name: "demo-data-config"
|
||||
data: {
|
||||
USE_DEMO_DATA: "True"
|
||||
DEMO_LOGIN_USERNAME: "testuser"
|
||||
// All demo user accounts are hardcoded to use the login password 'bankofanthos'
|
||||
DEMO_LOGIN_PASSWORD: "bankofanthos"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-frontend"
|
||||
Namespace: #BankOfHolos.Frontend.Namespace
|
||||
|
||||
// Ensure resources go in the correct namespace
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
|
||||
// https://github.com/GoogleCloudPlatform/bank-of-anthos/blob/release/v0.6.5/kubernetes-manifests/frontend.yaml
|
||||
Resources: {
|
||||
Service: frontend: {
|
||||
metadata: name: "frontend"
|
||||
metadata: labels: {
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
selector: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
_ports: http: {
|
||||
name: "http"
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: "TCP"
|
||||
}
|
||||
ports: [for x in _ports {x}]
|
||||
}
|
||||
}
|
||||
|
||||
Deployment: frontend: {
|
||||
metadata: name: "frontend"
|
||||
metadata: labels: {
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
template: {
|
||||
metadata: labels: {
|
||||
app: "frontend"
|
||||
application: "bank-of-holos"
|
||||
environment: "development"
|
||||
team: "frontend"
|
||||
tier: "web"
|
||||
}
|
||||
spec: {
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
fsGroup: 1000
|
||||
runAsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
}
|
||||
serviceAccountName: "bank-of-holos"
|
||||
terminationGracePeriodSeconds: 5
|
||||
containers: [{
|
||||
env: [{
|
||||
name: "BANK_NAME"
|
||||
value: "Bank of Holos"
|
||||
}, {
|
||||
name: "ENV_PLATFORM"
|
||||
value: "local"
|
||||
}, {
|
||||
name: "VERSION"
|
||||
value: "v0.6.5"
|
||||
}, {
|
||||
name: "PORT"
|
||||
value: "8080"
|
||||
}, {
|
||||
name: "ENABLE_TRACING"
|
||||
value: "false"
|
||||
}, {
|
||||
name: "SCHEME"
|
||||
value: "https"
|
||||
}, {
|
||||
name: "LOG_LEVEL"
|
||||
value: "info"
|
||||
}, {
|
||||
name: "DEFAULT_USERNAME"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_LOGIN_USERNAME"
|
||||
name: "demo-data-config"
|
||||
}
|
||||
}, {
|
||||
name: "DEFAULT_PASSWORD"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_LOGIN_PASSWORD"
|
||||
name: "demo-data-config"
|
||||
}
|
||||
}, {
|
||||
name: "REGISTERED_OAUTH_CLIENT_ID"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_OAUTH_CLIENT_ID"
|
||||
name: "oauth-config"
|
||||
optional: true
|
||||
}
|
||||
}, {
|
||||
name: "ALLOWED_OAUTH_REDIRECT_URI"
|
||||
valueFrom: configMapKeyRef: {
|
||||
key: "DEMO_OAUTH_REDIRECT_URI"
|
||||
name: "oauth-config"
|
||||
optional: true
|
||||
}
|
||||
}]
|
||||
envFrom: [{
|
||||
configMapRef: name: "environment-config"
|
||||
}, {
|
||||
configMapRef: name: "service-api-config"
|
||||
}]
|
||||
image: "us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/frontend:v0.6.5@sha256:d72050f70d12383e4434ad04d189b681dc625f696087ddf0b5df641645c9dafa"
|
||||
livenessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 30
|
||||
}
|
||||
name: "front"
|
||||
readinessProbe: {
|
||||
httpGet: {
|
||||
path: "/ready"
|
||||
port: 8080
|
||||
}
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 10
|
||||
}
|
||||
resources: {
|
||||
limits: {
|
||||
cpu: "250m"
|
||||
memory: "128Mi"
|
||||
}
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "64Mi"
|
||||
}
|
||||
}
|
||||
securityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities: drop: ["all"]
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
}
|
||||
volumeMounts: [{
|
||||
mountPath: "/tmp"
|
||||
name: "tmp"
|
||||
}, {
|
||||
mountPath: "/tmp/.ssh"
|
||||
name: "publickey"
|
||||
readOnly: true
|
||||
}]
|
||||
}]
|
||||
volumes: [
|
||||
{
|
||||
emptyDir: {}
|
||||
name: "tmp"
|
||||
},
|
||||
{
|
||||
name: "publickey"
|
||||
secret: {
|
||||
items: [{key: "jwtRS256.key.pub", path: "publickey"}]
|
||||
secretName: "jwt-key"
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow HTTPRoutes in the ingress gateway namespace to reference Services
|
||||
// in this namespace.
|
||||
ReferenceGrant: grant: #ReferenceGrant & {
|
||||
metadata: namespace: Namespace
|
||||
}
|
||||
|
||||
// Include shared resources
|
||||
#BankOfHolos.Resources
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#ArgoConfig: AppProject: #AppProjects["bank-frontend"].metadata.name
|
||||
@@ -0,0 +1,165 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
)
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
// This may be useful to copy and generate other secrets.
|
||||
let SecretName = "jwt-key"
|
||||
|
||||
// Roles for reading and writing secrets
|
||||
let Reader = "\(SecretName)-reader"
|
||||
let Writer = "\(SecretName)-writer"
|
||||
|
||||
// AllowedName represents the service account allowed to read the generated
|
||||
// secret.
|
||||
let AllowedName = #BankOfHolos.Name
|
||||
|
||||
let Objects = {
|
||||
Name: "bank-secrets"
|
||||
Namespace: #BankOfHolos.Security.Namespace
|
||||
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: [_]: [ID=string]: metadata: name: string | *ID
|
||||
|
||||
Resources: {
|
||||
// Kubernetes ServiceAccount used by the secret generator job.
|
||||
ServiceAccount: (Writer): corev1.#ServiceAccount
|
||||
// Role to allow the ServiceAccount to update secrets.
|
||||
Role: (Writer): rbacv1.#Role & {
|
||||
rules: [{
|
||||
apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["create", "update", "patch"]
|
||||
}]
|
||||
}
|
||||
// Bind the role to the service account.
|
||||
RoleBinding: (Writer): rbacv1.#RoleBinding & {
|
||||
roleRef: {
|
||||
apiGroup: "rbac.authorization.k8s.io"
|
||||
kind: "Role"
|
||||
name: Role[Writer].metadata.name
|
||||
}
|
||||
subjects: [{
|
||||
kind: "ServiceAccount"
|
||||
name: ServiceAccount[Writer].metadata.name
|
||||
namespace: Namespace
|
||||
}]
|
||||
}
|
||||
|
||||
let JobSpec = {
|
||||
serviceAccountName: Writer
|
||||
restartPolicy: "OnFailure"
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
runAsNonRoot: true
|
||||
runAsUser: 8192 // app
|
||||
}
|
||||
containers: [
|
||||
{
|
||||
name: "toolkit"
|
||||
image: "quay.io/holos-run/toolkit:2024-09-16"
|
||||
securityContext: {
|
||||
capabilities: drop: ["ALL"]
|
||||
allowPrivilegeEscalation: false
|
||||
}
|
||||
command: ["/bin/bash"]
|
||||
args: ["/config/entrypoint"]
|
||||
env: [{
|
||||
name: "HOME"
|
||||
value: "/tmp"
|
||||
}]
|
||||
volumeMounts: [{
|
||||
name: "config"
|
||||
mountPath: "/config"
|
||||
readOnly: true
|
||||
}]
|
||||
},
|
||||
]
|
||||
volumes: [{
|
||||
name: "config"
|
||||
configMap: name: Writer
|
||||
}]
|
||||
}
|
||||
|
||||
Job: (Writer): batchv1.#Job & {
|
||||
spec: template: spec: JobSpec
|
||||
}
|
||||
|
||||
ConfigMap: (Writer): corev1.#ConfigMap & {
|
||||
data: entrypoint: ENTRYPOINT
|
||||
}
|
||||
|
||||
// Allow the SecretStore in the frontend and backend namespaces to read the
|
||||
// secret.
|
||||
Role: (Reader): rbacv1.#Role & {
|
||||
rules: [{
|
||||
apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
resourceNames: [SecretName]
|
||||
verbs: ["get"]
|
||||
}]
|
||||
}
|
||||
|
||||
// Grant access to the bank-of-holos service account in the frontend and
|
||||
// backend namespaces.
|
||||
RoleBinding: (Reader): rbacv1.#RoleBinding & {
|
||||
roleRef: {
|
||||
apiGroup: "rbac.authorization.k8s.io"
|
||||
kind: "Role"
|
||||
name: Role[Reader].metadata.name
|
||||
}
|
||||
subjects: [{
|
||||
kind: "ServiceAccount"
|
||||
name: AllowedName
|
||||
namespace: #BankOfHolos.Frontend.Namespace
|
||||
}, {
|
||||
kind: "ServiceAccount"
|
||||
name: AllowedName
|
||||
namespace: #BankOfHolos.Backend.Namespace
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let ENTRYPOINT = """
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
status=$?
|
||||
rm -rf "${tmpdir}"
|
||||
return $status
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cd "$tmpdir"
|
||||
mkdir secret
|
||||
cd secret
|
||||
|
||||
echo "generating private key" >&2
|
||||
ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key -q -N "" -C \(AllowedName)
|
||||
echo "generating public key" >&2
|
||||
ssh-keygen -e -m PKCS8 -f jwtRS256.key > jwtRS256.key.pub
|
||||
cd ..
|
||||
|
||||
echo "copying secret into kubernetes manifest secret.yaml" >&2
|
||||
kubectl create secret generic \(SecretName) --from-file=secret --dry-run=client -o yaml > secret.yaml
|
||||
|
||||
echo "applying secret.yaml" >&2
|
||||
kubectl apply --server-side=true -f secret.yaml
|
||||
|
||||
echo "cleaning up" >&2
|
||||
rm -rf secret secret.yaml
|
||||
|
||||
echo "ok done" >&2
|
||||
"""
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#ArgoConfig: AppProject: #AppProjects["bank-security"].metadata.name
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "bank-of-holos",
|
||||
"short": "demo bank composed of two projects",
|
||||
"long": "Bank of Holos is a sample HTTP-based web app that simulates a bank's payment processing network, allowing users to create artificial bank accounts and complete transactions."
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package holos
|
||||
|
||||
// Platform wide configuration
|
||||
#CertManager: {
|
||||
Version: "{{ .Version }}"
|
||||
Namespace: "{{ .Namespace }}"
|
||||
}
|
||||
|
||||
// Register the namespace
|
||||
#Namespaces: (#CertManager.Namespace): _
|
||||
|
||||
// Manage the component on every cluster in the platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/{{ .Name }}": {
|
||||
path: "components/cert-manager"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
let Chart = {
|
||||
Name: "{{ .Name }}"
|
||||
Version: #CertManager.Version
|
||||
Namespace: #CertManager.Namespace
|
||||
|
||||
Repo: name: "{{ .RepoName }}"
|
||||
Repo: url: "{{ .RepoURL }}"
|
||||
|
||||
Values: installCRDs: true
|
||||
Values: startupapicheck: enabled: false
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "cert-manager",
|
||||
"short": "cloud native X.509 certificate management for kubernetes",
|
||||
"long": "cert-manager creates tls certificates for workloads in your kubernetes cluster and renews the certificates before they expire.",
|
||||
"chart": "",
|
||||
"reponame": "jetstack",
|
||||
"repourl": "https://charts.jetstack.io",
|
||||
"version": "1.15.3",
|
||||
"namespace": "cert-manager"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
// Manage the component on every cluster in the platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/external-secrets-crds": {
|
||||
path: "projects/platform/components/external-secrets-crds"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
#Platform: Components: "\(Cluster.name)/external-secrets": {
|
||||
path: "projects/platform/components/external-secrets"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package holos
|
||||
|
||||
// Platform wide configuration
|
||||
#ExternalSecrets: {
|
||||
Version: "{{ .Version }}"
|
||||
Namespace: "external-secrets"
|
||||
}
|
||||
|
||||
// Register the namespace
|
||||
#Namespaces: (#ExternalSecrets.Namespace): _
|
||||
@@ -0,0 +1,33 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
ks "sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
(#Kubernetes & {Name: "external-secrets-crds"}).BuildPlan
|
||||
|
||||
// Holos stages BuildPlan resources as an intermediate step of the rendering
|
||||
// pipeline. The purpose is to provide the resources to kustomize for
|
||||
// post-processing.
|
||||
let BuildPlanResources = "build-plan-resources.yaml"
|
||||
|
||||
_Kustomization: ks.#Kustomization & {
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1"
|
||||
kind: "Kustomization"
|
||||
resources: [
|
||||
// Kustomize the intermediate build plan resources.
|
||||
BuildPlanResources,
|
||||
// Mix-in external resources.
|
||||
"https://raw.githubusercontent.com/external-secrets/external-secrets/v\(#ExternalSecrets.Version)/deploy/crds/bundle.yaml",
|
||||
]
|
||||
}
|
||||
|
||||
// Generate a kustomization.yaml directly from CUE so we can provide the correct
|
||||
// version.
|
||||
spec: components: kubernetesObjectsList: [{
|
||||
// intermediate build plan resources to kustomize. Necessary to activate the
|
||||
// kustomization post-rendering step in holos.
|
||||
kustomize: resourcesFile: BuildPlanResources
|
||||
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(_Kustomization)
|
||||
}]
|
||||
@@ -0,0 +1,50 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
ks "sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
// Patch the the build plan output.
|
||||
_Kustomization: patches: [for x in KustomizePatches {x}]
|
||||
|
||||
#KustomizePatches: [ArbitraryLabel=string]: ks.#Patch
|
||||
let KustomizePatches = #KustomizePatches & {
|
||||
let Patch = [{
|
||||
op: "replace"
|
||||
path: "/spec/conversion/webhook/clientConfig/service/name"
|
||||
value: "external-secrets-webhook"
|
||||
}, {
|
||||
op: "replace"
|
||||
path: "/spec/conversion/webhook/clientConfig/service/namespace"
|
||||
value: "external-secrets"
|
||||
}]
|
||||
|
||||
clustersecretstores: {
|
||||
target: {
|
||||
group: "apiextensions.k8s.io"
|
||||
version: "v1"
|
||||
kind: "CustomResourceDefinition"
|
||||
name: "clustersecretstores.external-secrets.io"
|
||||
}
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
externalsecrets: {
|
||||
target: {
|
||||
group: "apiextensions.k8s.io"
|
||||
version: "v1"
|
||||
kind: "CustomResourceDefinition"
|
||||
name: "externalsecrets.external-secrets.io"
|
||||
}
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
secretstores: {
|
||||
target: {
|
||||
group: "apiextensions.k8s.io"
|
||||
version: "v1"
|
||||
kind: "CustomResourceDefinition"
|
||||
name: "secretstores.external-secrets.io"
|
||||
}
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
_Chart: {
|
||||
Name: "external-secrets"
|
||||
Version: "0.10.3"
|
||||
Namespace: "external-secrets"
|
||||
|
||||
Repo: name: "external-secrets"
|
||||
Repo: url: "https://charts.external-secrets.io"
|
||||
|
||||
Values: installCRDs: false
|
||||
}
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & _Chart).BuildPlan
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "external-secrets",
|
||||
"short": "safer secret management",
|
||||
"long": "https://external-secrets.io",
|
||||
"version": "0.10.3"
|
||||
}
|
||||
@@ -4,7 +4,7 @@ package holos
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/gateway-api": {
|
||||
path: "components/gateway-api"
|
||||
path: "projects/platform/components/gateway-api"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubectl kustomize build plan.
|
||||
(#Kustomize & {Name: "gateway-api"}).Output
|
||||
(#Kustomize & {Name: "gateway-api"}).BuildPlan
|
||||
@@ -0,0 +1,37 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let Objects = {
|
||||
Name: "{{ .Name }}"
|
||||
Namespace: #Istio.Gateway.Namespace
|
||||
|
||||
Resources: [_]: [_]: metadata: namespace: Namespace
|
||||
Resources: HTTPRoute: (#HTTPRouteClone & {Name: "httpbin"}).BuildPlan
|
||||
}
|
||||
|
||||
#HTTPRouteClone: {
|
||||
Name: string
|
||||
let Host = "\(Name).\(#Platform.Domain)"
|
||||
Output: "\(Name)": {
|
||||
metadata: namespace: _
|
||||
metadata: name: Name
|
||||
metadata: labels: app: Name
|
||||
spec: hostnames: [Host]
|
||||
spec: parentRefs: [{
|
||||
name: "default"
|
||||
namespace: metadata.namespace
|
||||
}]
|
||||
spec: rules: [
|
||||
{
|
||||
matches: [{path: {type: "PathPrefix", value: "/"}}]
|
||||
backendRefs: [{
|
||||
name: Name
|
||||
namespace: #HTTPBin.Namespace
|
||||
port: #HTTPBin.Port
|
||||
}]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package holos
|
||||
|
||||
// Manage the component on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/{{ .Name }}": {
|
||||
path: "components/httpbin/routes"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "httpbin-routes",
|
||||
"short": "expose httpbin with httproute resources",
|
||||
"long": "expose httpbin with httproute resources",
|
||||
"namespace": "istio-ingress"
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let Objects = {
|
||||
Name: "{{ .Name }}"
|
||||
Namespace: #HTTPBin.Namespace
|
||||
|
||||
// Constrain resources to the httpbin namespace
|
||||
Resources: [_]: [_]: metadata: namespace: #HTTPBin.Namespace
|
||||
|
||||
Resources: {
|
||||
Deployment: httpbin: {
|
||||
metadata: name: "httpbin"
|
||||
metadata: labels: app: metadata.name
|
||||
spec: {
|
||||
selector: matchLabels: {
|
||||
app: metadata.labels.app
|
||||
"app.kubernetes.io/instance": app
|
||||
}
|
||||
|
||||
template: {
|
||||
metadata: labels: selector.matchLabels
|
||||
spec: securityContext: seccompProfile: type: "RuntimeDefault"
|
||||
spec: containers: [{
|
||||
name: "httpbin"
|
||||
image: "quay.io/holos/mccutchen/go-httpbin"
|
||||
ports: [{containerPort: 8080}]
|
||||
securityContext: {
|
||||
seccompProfile: type: "RuntimeDefault"
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 8192
|
||||
runAsGroup: 8192
|
||||
capabilities: drop: ["ALL"]
|
||||
}}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Service: httpbin: {
|
||||
metadata: labels: Deployment.httpbin.metadata.labels
|
||||
spec: {
|
||||
selector: Deployment.httpbin.spec.selector.matchLabels
|
||||
_ports: http: {
|
||||
port: #HTTPBin.Port
|
||||
targetPort: Deployment.httpbin.spec.template.spec.containers[0].ports[0].containerPort
|
||||
protocol: "TCP"
|
||||
name: "http"
|
||||
}
|
||||
ports: [for x in _ports {x}]
|
||||
}
|
||||
}
|
||||
|
||||
// Allow istio-ingress to refer to Services from HTTPRoutes
|
||||
ReferenceGrant: httpbin: #ReferenceGrant & {
|
||||
metadata: labels: Deployment.httpbin.metadata.labels
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package holos
|
||||
|
||||
// Platform wide configuration
|
||||
#HTTPBin: {
|
||||
Namespace: "{{ .Namespace }}"
|
||||
Port: 80
|
||||
}
|
||||
|
||||
// Register the namespace
|
||||
#Namespaces: (#HTTPBin.Namespace): _
|
||||
|
||||
// Manage the component on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/{{ .Name }}": {
|
||||
path: "components/httpbin/workload"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "httpbin-workload",
|
||||
"short": "manages the httpbin deployment and service",
|
||||
"long": "httpbin is useful to inspect requests and responses",
|
||||
"namespace": "httpbin"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package holos
|
||||
|
||||
// Manage on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/httproutes": {
|
||||
path: "projects/platform/components/httproutes"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package holos
|
||||
|
||||
import v1 "gateway.networking.k8s.io/httproute/v1"
|
||||
|
||||
// #HTTPRoutes defines managed HTTPRoute resources for the platform. These
|
||||
// resources are managed in the istio-ingress namespace. Other components
|
||||
// define the routes they need close to the root of configuration.
|
||||
#HTTPRoutes: {
|
||||
// For the guides, we simplify this down to a flat namespace.
|
||||
[Name=string]: v1.#HTTPRoute & {
|
||||
let HOST = Name + "." + #Platform.Domain
|
||||
|
||||
_backendRefs: [NAME=string]: {
|
||||
name: NAME
|
||||
namespace: string
|
||||
port: number | *80
|
||||
}
|
||||
|
||||
metadata: name: Name
|
||||
metadata: namespace: #Istio.Gateway.Namespace
|
||||
metadata: labels: app: Name
|
||||
spec: hostnames: [HOST]
|
||||
spec: parentRefs: [{
|
||||
name: "default"
|
||||
namespace: metadata.namespace
|
||||
}]
|
||||
spec: rules: [
|
||||
{
|
||||
matches: [{path: {type: "PathPrefix", value: "/"}}]
|
||||
backendRefs: [for x in _backendRefs {x}]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package holos
|
||||
|
||||
let Objects = {
|
||||
Name: "httproutes"
|
||||
Resources: HTTPRoute: #HTTPRoutes
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "httproutes",
|
||||
"short": "#HTTPRoutes registration point",
|
||||
"long": "Provides the #HTTPRoutes registration point to manage httproutes in the istio-ingress namespace."
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let Objects = {
|
||||
Name: "{{ .Name }}"
|
||||
Namespace: #Istio.Gateway.Namespace
|
||||
|
||||
Resources: {
|
||||
// The default gateway with all listeners attached to tls certs.
|
||||
Gateway: default: {
|
||||
metadata: namespace: Namespace
|
||||
|
||||
let Listeners = {
|
||||
http: {
|
||||
name: "http"
|
||||
protocol: "HTTP"
|
||||
port: 80
|
||||
allowedRoutes: namespaces: from: "Same"
|
||||
}
|
||||
https: {
|
||||
name: "https"
|
||||
protocol: "HTTPS"
|
||||
port: 443
|
||||
allowedRoutes: namespaces: from: "Same"
|
||||
tls: mode: "Terminate"
|
||||
tls: certificateRefs: [{
|
||||
kind: "Secret"
|
||||
name: "gateway-cert"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
spec: listeners: [for x in Listeners {x}]
|
||||
}
|
||||
|
||||
// Manage a simple cert for example.com and *.example.com
|
||||
Certificate: "gateway-cert": {
|
||||
metadata: name: "gateway-cert"
|
||||
metadata: namespace: Namespace
|
||||
spec: commonName: #Platform.Domain
|
||||
spec: dnsNames: [spec.commonName, "*.\(spec.commonName)"]
|
||||
spec: secretName: metadata.name
|
||||
spec: issuerRef: {
|
||||
kind: "ClusterIssuer"
|
||||
name: "local-ca"
|
||||
}
|
||||
}
|
||||
|
||||
// Manage a service account to prevent ArgoCD from pruning it.
|
||||
ServiceAccount: "default-istio": {
|
||||
metadata: namespace: Namespace
|
||||
metadata: labels: {
|
||||
"gateway.istio.io/managed": "istio.io-gateway-controller"
|
||||
"gateway.networking.k8s.io/gateway-name": "default"
|
||||
"istio.io/gateway-name": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Gateway API
|
||||
|
||||
This component uses the [Gateway API][1] to manage an istio Gateway. This will
|
||||
become the default method in upstream istio so it is the preferred method in
|
||||
Holos.
|
||||
|
||||
[1]: https://gateway-api.sigs.k8s.io/
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
#Istio: Gateway: Namespace: "istio-ingress"
|
||||
|
||||
// Register the Namespaces
|
||||
#Namespaces: (#Istio.Gateway.Namespace): _
|
||||
|
||||
// Manage istio on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: {
|
||||
"\(Cluster.name)/{{ .Name }}": {
|
||||
path: "components/istio/gateway"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "istio-gateway",
|
||||
"short": "kubernetes ingress gateway api",
|
||||
"long": "Gateway API ingress gateway with certificate management"
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-gateway"
|
||||
Version: #Istio.Version
|
||||
Namespace: #Istio.Gateway.Namespace
|
||||
|
||||
Chart: chart: name: "gateway"
|
||||
|
||||
Repo: name: "istio"
|
||||
Repo: url: "https://istio-release.storage.googleapis.com/charts"
|
||||
|
||||
Values: #Istio.Values
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
package holos
|
||||
|
||||
// imported from the 1.23.1 gateway chart
|
||||
// cue import components/istio/gateway/vendor/gateway/values.yaml
|
||||
|
||||
#Istio: Values: {
|
||||
// "defaults" is a workaround for Helm limitations. Users should NOT set ".defaults" explicitly, but rather directly set the fields internally.
|
||||
// For instance, instead of `--set defaults.foo=bar`, just set `--set foo=bar`.
|
||||
defaults: {
|
||||
// Name allows overriding the release name. Generally this should not be set
|
||||
name: ""
|
||||
// revision declares which revision this gateway is a part of
|
||||
revision: ""
|
||||
|
||||
// Controls the spec.replicas setting for the Gateway deployment if set.
|
||||
// Otherwise defaults to Kubernetes Deployment default (1).
|
||||
replicaCount: null
|
||||
kind: "Deployment"
|
||||
rbac: {
|
||||
// If enabled, roles will be created to enable accessing certificates from Gateways. This is not needed
|
||||
// when using http://gateway-api.org/.
|
||||
enabled: true
|
||||
}
|
||||
serviceAccount: {
|
||||
// If set, a service account will be created. Otherwise, the default is used
|
||||
create: true
|
||||
// Annotations to add to the service account
|
||||
annotations: {}
|
||||
// The name of the service account to use.
|
||||
// If not set, the release name is used
|
||||
name: ""
|
||||
}
|
||||
podAnnotations: {
|
||||
"prometheus.io/port": "15020"
|
||||
"prometheus.io/scrape": "true"
|
||||
"prometheus.io/path": "/stats/prometheus"
|
||||
"inject.istio.io/templates": "gateway"
|
||||
"sidecar.istio.io/inject": "true"
|
||||
}
|
||||
|
||||
// Define the security context for the pod.
|
||||
// If unset, this will be automatically set to the minimum privileges required to bind to port 80 and 443.
|
||||
// On Kubernetes 1.22+, this only requires the `net.ipv4.ip_unprivileged_port_start` sysctl.
|
||||
securityContext: {}
|
||||
containerSecurityContext: {}
|
||||
service: {
|
||||
// Type of service. Set to "None" to disable the service entirely
|
||||
type: "LoadBalancer"
|
||||
ports: [{
|
||||
name: "status-port"
|
||||
port: 15021
|
||||
protocol: "TCP"
|
||||
targetPort: 15021
|
||||
}, {
|
||||
name: "http2"
|
||||
port: 80
|
||||
protocol: "TCP"
|
||||
targetPort: 80
|
||||
}, {
|
||||
name: "https"
|
||||
port: 443
|
||||
protocol: "TCP"
|
||||
targetPort: 443
|
||||
}]
|
||||
annotations: {}
|
||||
loadBalancerIP: ""
|
||||
loadBalancerSourceRanges: []
|
||||
externalTrafficPolicy: ""
|
||||
externalIPs: []
|
||||
ipFamilyPolicy: ""
|
||||
//# Whether to automatically allocate NodePorts (only for LoadBalancers).
|
||||
// allocateLoadBalancerNodePorts: false
|
||||
ipFamilies: []
|
||||
}
|
||||
resources: {
|
||||
requests: {
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
}
|
||||
limits: {
|
||||
cpu: "2000m"
|
||||
memory: "1024Mi"
|
||||
}
|
||||
}
|
||||
autoscaling: {
|
||||
enabled: true
|
||||
minReplicas: 1
|
||||
maxReplicas: 5
|
||||
targetCPUUtilizationPercentage: 80
|
||||
targetMemoryUtilizationPercentage: {}
|
||||
autoscaleBehavior: {}
|
||||
}
|
||||
|
||||
// Pod environment variables
|
||||
env: {}
|
||||
|
||||
// Labels to apply to all resources
|
||||
labels: {}
|
||||
|
||||
// Annotations to apply to all resources
|
||||
annotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
topologySpreadConstraints: []
|
||||
affinity: {}
|
||||
|
||||
// If specified, the gateway will act as a network gateway for the given network.
|
||||
networkGateway: ""
|
||||
|
||||
// Specify image pull policy if default behavior isn't desired.
|
||||
// Default behavior: latest images will be Always else IfNotPresent
|
||||
imagePullPolicy: ""
|
||||
imagePullSecrets: []
|
||||
|
||||
// This value is used to configure a Kubernetes PodDisruptionBudget for the gateway.
|
||||
//
|
||||
// By default, the `podDisruptionBudget` is disabled (set to `{}`),
|
||||
// which means that no PodDisruptionBudget resource will be created.
|
||||
//
|
||||
// To enable the PodDisruptionBudget, configure it by specifying the
|
||||
// `minAvailable` or `maxUnavailable`. For example, to set the
|
||||
// minimum number of available replicas to 1, you can update this value as follows:
|
||||
//
|
||||
// podDisruptionBudget:
|
||||
// minAvailable: 1
|
||||
//
|
||||
// Or, to allow a maximum of 1 unavailable replica, you can set:
|
||||
//
|
||||
// podDisruptionBudget:
|
||||
// maxUnavailable: 1
|
||||
//
|
||||
// You can also specify the `unhealthyPodEvictionPolicy` field, and the valid values are `IfHealthyBudget` and `AlwaysAllow`.
|
||||
// For example, to set the `unhealthyPodEvictionPolicy` to `AlwaysAllow`, you can update this value as follows:
|
||||
//
|
||||
// podDisruptionBudget:
|
||||
// minAvailable: 1
|
||||
// unhealthyPodEvictionPolicy: AlwaysAllow
|
||||
//
|
||||
// To disable the PodDisruptionBudget, you can leave it as an empty object `{}`:
|
||||
//
|
||||
// podDisruptionBudget: {}
|
||||
//
|
||||
podDisruptionBudget: {}
|
||||
terminationGracePeriodSeconds: 30
|
||||
|
||||
// A list of `Volumes` added into the Gateway Pods. See
|
||||
// https://kubernetes.io/docs/concepts/storage/volumes/.
|
||||
volumes: []
|
||||
|
||||
// A list of `VolumeMounts` added into the Gateway Pods. See
|
||||
// https://kubernetes.io/docs/concepts/storage/volumes/.
|
||||
volumeMounts: []
|
||||
|
||||
// Configure this to a higher priority class in order to make sure your Istio gateway pods
|
||||
// will not be killed because of low priority class.
|
||||
// Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass
|
||||
// for more detail.
|
||||
priorityClassName: ""
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
#Istio: {
|
||||
Version: "1.23.1"
|
||||
System: Namespace: "istio-system"
|
||||
Gateway: Namespace: "istio-ingress"
|
||||
|
||||
// Constrain Helm values for safer, easier upgrades and consistency across
|
||||
// platform components.
|
||||
Values: global: istioNamespace: System.Namespace
|
||||
|
||||
// Configure ambient mode
|
||||
Values: profile: "ambient"
|
||||
}
|
||||
|
||||
// Register the Namespaces
|
||||
#Namespaces: (#Istio.System.Namespace): _
|
||||
#Namespaces: (#Istio.Gateway.Namespace): _
|
||||
|
||||
// Manage istio on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: {
|
||||
"\(Cluster.name)/istio-base": {
|
||||
path: "components/istio/base"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istiod": {
|
||||
path: "components/istio/istiod"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-cni": {
|
||||
path: "components/istio/cni"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-ztunnel": {
|
||||
path: "components/istio/ztunnel"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-gateway": {
|
||||
path: "components/istio/gateway"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
// Manage istio on workload clusters
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: {
|
||||
"\(Cluster.name)/istio-base": {
|
||||
path: "projects/platform/components/istio/base"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istiod": {
|
||||
path: "projects/platform/components/istio/istiod"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-cni": {
|
||||
path: "projects/platform/components/istio/cni"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
"\(Cluster.name)/istio-ztunnel": {
|
||||
path: "projects/platform/components/istio/ztunnel"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
// #Istio represents platform wide configuration
|
||||
#Istio: {
|
||||
Version: "1.23.1"
|
||||
System: Namespace: "istio-system"
|
||||
|
||||
// Constrain Helm values for safer, easier upgrades and consistency across
|
||||
// platform components.
|
||||
Values: global: istioNamespace: System.Namespace
|
||||
|
||||
// Configure ambient mode
|
||||
Values: profile: "ambient"
|
||||
}
|
||||
|
||||
// Register the Namespaces
|
||||
#Namespaces: (#Istio.System.Namespace): _
|
||||
@@ -1,7 +1,7 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-base"
|
||||
@@ -0,0 +1,48 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
ks "sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
// Holos stages BuildPlan resources as an intermediate step of the rendering
|
||||
// pipeline. The purpose is to provide the resources to kustomize for
|
||||
// post-processing.
|
||||
let BuildPlanOutputManifest = "build-plan-output-manifest.yaml"
|
||||
|
||||
// Patch istio so it's not constantly out of sync in ArgoCD
|
||||
let Kustomization = ks.#Kustomization & {
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1"
|
||||
kind: "Kustomization"
|
||||
// Kustomize the build plan output.
|
||||
resources: [BuildPlanOutputManifest]
|
||||
// Patch the the build plan output.
|
||||
patches: [for x in KustomizePatches {x}]
|
||||
}
|
||||
|
||||
#KustomizePatches: [ArbitraryLabel=string]: ks.#Patch
|
||||
let KustomizePatches = #KustomizePatches & {
|
||||
validator: {
|
||||
target: {
|
||||
group: "admissionregistration.k8s.io"
|
||||
version: "v1"
|
||||
kind: "ValidatingWebhookConfiguration"
|
||||
name: "istiod-default-validator"
|
||||
}
|
||||
let Patch = [{
|
||||
op: "replace"
|
||||
path: "/webhooks/0/failurePolicy"
|
||||
value: "Fail"
|
||||
}]
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a kustomization.yaml directly from CUE so we can provide the correct
|
||||
// version.
|
||||
spec: components: helmChartList: [{
|
||||
// intermediate build plan resources to kustomize. Necessary to activate the
|
||||
// kustomization post-rendering step in holos.
|
||||
kustomize: resourcesFile: BuildPlanOutputManifest
|
||||
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(Kustomization)
|
||||
}]
|
||||
@@ -1,7 +1,7 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-cni"
|
||||
@@ -0,0 +1,61 @@
|
||||
package holos
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let Objects = {
|
||||
Name: "istio-gateway"
|
||||
Namespace: #Istio.Gateway.Namespace
|
||||
|
||||
Resources: {
|
||||
// The default gateway with all listeners attached to tls certs.
|
||||
Gateway: default: {
|
||||
metadata: namespace: Namespace
|
||||
|
||||
let Listeners = {
|
||||
http: {
|
||||
name: "http"
|
||||
protocol: "HTTP"
|
||||
port: 80
|
||||
allowedRoutes: namespaces: from: "Same"
|
||||
}
|
||||
https: {
|
||||
name: "https"
|
||||
protocol: "HTTPS"
|
||||
port: 443
|
||||
allowedRoutes: namespaces: from: "Same"
|
||||
tls: mode: "Terminate"
|
||||
tls: certificateRefs: [{
|
||||
kind: "Secret"
|
||||
name: "gateway-cert"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
spec: listeners: [for x in Listeners {x}]
|
||||
}
|
||||
|
||||
// Manage a simple cert for example.com and *.example.com
|
||||
Certificate: "gateway-cert": {
|
||||
metadata: name: "gateway-cert"
|
||||
metadata: namespace: Namespace
|
||||
spec: commonName: #Platform.Domain
|
||||
spec: dnsNames: [spec.commonName, "*.\(spec.commonName)"]
|
||||
spec: secretName: metadata.name
|
||||
spec: issuerRef: {
|
||||
kind: "ClusterIssuer"
|
||||
name: "local-ca"
|
||||
}
|
||||
}
|
||||
|
||||
// Manage a service account to prevent ArgoCD from pruning it.
|
||||
ServiceAccount: "default-istio": {
|
||||
metadata: namespace: Namespace
|
||||
metadata: labels: {
|
||||
"gateway.istio.io/managed": "istio.io-gateway-controller"
|
||||
"gateway.networking.k8s.io/gateway-name": "default"
|
||||
"istio.io/gateway-name": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Gateway API
|
||||
|
||||
This component uses the [Gateway API][1] to manage an istio Gateway. This will
|
||||
become the default method in upstream istio so it is the preferred method in
|
||||
Holos.
|
||||
|
||||
[1]: https://gateway-api.sigs.k8s.io/
|
||||
@@ -0,0 +1,48 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/yaml"
|
||||
ks "sigs.k8s.io/kustomize/api/types"
|
||||
)
|
||||
|
||||
// Holos stages BuildPlan resources as an intermediate step of the rendering
|
||||
// pipeline. The purpose is to provide the resources to kustomize for
|
||||
// post-processing.
|
||||
let BuildPlanOutputManifest = "build-plan-output-manifest.yaml"
|
||||
|
||||
// Patch istio so it's not constantly out of sync in ArgoCD
|
||||
let Kustomization = ks.#Kustomization & {
|
||||
apiVersion: "kustomize.config.k8s.io/v1beta1"
|
||||
kind: "Kustomization"
|
||||
// Kustomize the build plan output.
|
||||
resources: [BuildPlanOutputManifest]
|
||||
// Patch the the build plan output.
|
||||
patches: [for x in KustomizePatches {x}]
|
||||
}
|
||||
|
||||
#KustomizePatches: [ArbitraryLabel=string]: ks.#Patch
|
||||
let KustomizePatches = #KustomizePatches & {
|
||||
validator: {
|
||||
target: {
|
||||
group: "admissionregistration.k8s.io"
|
||||
version: "v1"
|
||||
kind: "ValidatingWebhookConfiguration"
|
||||
name: "istio-validator-istio-system"
|
||||
}
|
||||
let Patch = [{
|
||||
op: "replace"
|
||||
path: "/webhooks/0/failurePolicy"
|
||||
value: "Fail"
|
||||
}]
|
||||
patch: yaml.Marshal(Patch)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a kustomization.yaml directly from CUE so we can provide the correct
|
||||
// version.
|
||||
spec: components: helmChartList: [{
|
||||
// intermediate build plan resources to kustomize. Necessary to activate the
|
||||
// kustomization post-rendering step in holos.
|
||||
kustomize: resourcesFile: BuildPlanOutputManifest
|
||||
kustomize: kustomizeFiles: "kustomization.yaml": yaml.Marshal(Kustomization)
|
||||
}]
|
||||
@@ -1,7 +1,7 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
let Chart = {
|
||||
Name: "istiod"
|
||||
@@ -1,7 +1,7 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
let Chart = {
|
||||
Name: "istio-ztunnel"
|
||||
@@ -0,0 +1,20 @@
|
||||
package holos
|
||||
|
||||
import ci "cert-manager.io/clusterissuer/v1"
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
let Objects = {
|
||||
Name: "local-ca"
|
||||
Namespace: #CertManager.Namespace
|
||||
|
||||
Resources: ClusterIssuer: LocalCA: ci.#ClusterIssuer & {
|
||||
metadata: name: "local-ca"
|
||||
metadata: namespace: #CertManager.Namespace
|
||||
|
||||
// The secret name must align with the local cluster guide at
|
||||
// https://holos.run/docs/guides/local-cluster/
|
||||
spec: ca: secretName: "local-ca"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package holos
|
||||
|
||||
// Manage the component on every cluster in the platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/{{ .Name }}": {
|
||||
path: "components/local-ca"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "local-ca",
|
||||
"short": "manages a cluster issuer for use with our guides",
|
||||
"long": "manages a cluster issuer that uses the mkcert ca private key to issue certs",
|
||||
"namespace": "cert-manager"
|
||||
}
|
||||
@@ -6,4 +6,4 @@ let Objects = {
|
||||
}
|
||||
|
||||
// Produce a kubernetes objects build plan.
|
||||
(#Kubernetes & Objects).Output
|
||||
(#Kubernetes & Objects).BuildPlan
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
let Chart = {
|
||||
Name: "{{ .Name }}"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package holos
|
||||
|
||||
import rg "gateway.networking.k8s.io/referencegrant/v1beta1"
|
||||
|
||||
#ReferenceGrant: rg.#ReferenceGrant & {
|
||||
metadata: name: #Istio.Gateway.Namespace
|
||||
metadata: namespace: string
|
||||
spec: from: [{
|
||||
group: "gateway.networking.k8s.io"
|
||||
kind: "HTTPRoute"
|
||||
namespace: #Istio.Gateway.Namespace
|
||||
}]
|
||||
spec: to: [{
|
||||
group: ""
|
||||
kind: "Service"
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "referencegrant",
|
||||
"short": "provides #ReferenceGrant at the root"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user