Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6041fd4d76 | ||
|
|
fec1de0004 | ||
|
|
6ad24a6eec | ||
|
|
57dedc6450 | ||
|
|
8d2a9dd659 | ||
|
|
e3c53f5655 | ||
|
|
3b833cdacd | ||
|
|
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 | ||
|
|
6f39cc6fdc | ||
|
|
e410563f82 | ||
|
|
0a53bef72a | ||
|
|
02a450e597 | ||
|
|
e1222cf367 | ||
|
|
740a3d21a1 | ||
|
|
1114b65a47 | ||
|
|
c9d892eee3 | ||
|
|
4c77eba72b | ||
|
|
a8ae56b08b | ||
|
|
b04837ede2 | ||
|
|
559c8bc79f | ||
|
|
a30335b171 | ||
|
|
108831747a | ||
|
|
c714a2b61e | ||
|
|
1cba383dc1 | ||
|
|
265d5773b8 | ||
|
|
44f8779136 | ||
|
|
4127804092 | ||
|
|
8f424cfabe | ||
|
|
699148abdd |
58
.cspell.json
@@ -5,45 +5,69 @@
|
||||
"mdx"
|
||||
],
|
||||
"words": [
|
||||
"admissionregistration",
|
||||
"apiextensions",
|
||||
"applicationset",
|
||||
"argoproj",
|
||||
"authcode",
|
||||
"authorizationpolicies",
|
||||
"authpolicy",
|
||||
"authproxy",
|
||||
"authroutes",
|
||||
"buildplan",
|
||||
"cainjector",
|
||||
"CAROOT",
|
||||
"certificaterequests",
|
||||
"certificatesigningrequests",
|
||||
"clsx",
|
||||
"clusterissuer",
|
||||
"clusterissuers",
|
||||
"clusterrole",
|
||||
"clusterrolebinding",
|
||||
"configmap",
|
||||
"cookiesecret",
|
||||
"coredns",
|
||||
"corev",
|
||||
"CRD's",
|
||||
"crds",
|
||||
"creds",
|
||||
"crossplane",
|
||||
"cuecontext",
|
||||
"cuelang",
|
||||
"customresourcedefinition",
|
||||
"daemonset",
|
||||
"destinationrules",
|
||||
"devicecode",
|
||||
"dnsmasq",
|
||||
"dscacheutil",
|
||||
"entgo",
|
||||
"envoyfilters",
|
||||
"errgroup",
|
||||
"fctr",
|
||||
"fieldmaskpb",
|
||||
"flushcache",
|
||||
"gatewayclasses",
|
||||
"gendoc",
|
||||
"ggnpl",
|
||||
"ghaction",
|
||||
"gitops",
|
||||
"godoc",
|
||||
"golangci",
|
||||
"goreleaser",
|
||||
"grpcreflect",
|
||||
"grpcroutes",
|
||||
"grpcurl",
|
||||
"holos",
|
||||
"holoslogger",
|
||||
"horizontalpodautoscaler",
|
||||
"httpbin",
|
||||
"httproute",
|
||||
"httproutes",
|
||||
"Infima",
|
||||
"isatty",
|
||||
"istiod",
|
||||
"jbrx",
|
||||
"jeffmccune",
|
||||
"jetstack",
|
||||
"Jsonnet",
|
||||
"killall",
|
||||
@@ -54,11 +78,17 @@
|
||||
"Kustomizations",
|
||||
"kustomize",
|
||||
"ldflags",
|
||||
"leaderelection",
|
||||
"libnss",
|
||||
"loadbalancer",
|
||||
"mattn",
|
||||
"mccutchen",
|
||||
"mindmap",
|
||||
"mktemp",
|
||||
"msqbn",
|
||||
"mtls",
|
||||
"Multicluster",
|
||||
"mutatingwebhookconfiguration",
|
||||
"mxcl",
|
||||
"myhostname",
|
||||
"nameserver",
|
||||
@@ -66,24 +96,43 @@
|
||||
"orgid",
|
||||
"otelconnect",
|
||||
"Parentspanid",
|
||||
"pcjc",
|
||||
"peerauthentications",
|
||||
"pflag",
|
||||
"pipefail",
|
||||
"PKCE",
|
||||
"platformconnect",
|
||||
"poddisruptionbudget",
|
||||
"podinfo",
|
||||
"portmapping",
|
||||
"promhttp",
|
||||
"protobuf",
|
||||
"protojson",
|
||||
"proxyconfigs",
|
||||
"Pulumi",
|
||||
"putenv",
|
||||
"qjbp",
|
||||
"quickstart",
|
||||
"referencegrant",
|
||||
"referencegrants",
|
||||
"requestauthentications",
|
||||
"retryable",
|
||||
"rolebinding",
|
||||
"ropc",
|
||||
"seccomp",
|
||||
"SECRETKEY",
|
||||
"secretstores",
|
||||
"serverlb",
|
||||
"serverside",
|
||||
"serviceaccount",
|
||||
"serviceentries",
|
||||
"spanid",
|
||||
"spiffe",
|
||||
"startupapicheck",
|
||||
"stefanprodan",
|
||||
"structpb",
|
||||
"subjectaccessreviews",
|
||||
"svclb",
|
||||
"systemconnect",
|
||||
"tablewriter",
|
||||
"Tiltfile",
|
||||
@@ -101,7 +150,14 @@
|
||||
"usecases",
|
||||
"userconnect",
|
||||
"userdata",
|
||||
"userservice",
|
||||
"validatingwebhookconfiguration",
|
||||
"virtualservices",
|
||||
"wasmplugins",
|
||||
"workloadentries",
|
||||
"workloadgroups",
|
||||
"zerolog",
|
||||
"zitadel"
|
||||
"zitadel",
|
||||
"ztunnel"
|
||||
]
|
||||
}
|
||||
|
||||
163
api/author/v1alpha3/definitions.go
Normal file
@@ -0,0 +1,163 @@
|
||||
// Package v1alpha3 contains CUE definitions intended as convenience wrappers
|
||||
// around the core data types defined in package core. The purpose of these
|
||||
// wrappers is to make life easier for platform engineers by reducing boiler
|
||||
// plate code and generating component build plans in a consistent manner.
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
//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 {
|
||||
ComponentFields `json:",inline"`
|
||||
|
||||
// Version represents the chart version.
|
||||
Version string
|
||||
// Namespace represents the helm namespace option when rendering the chart.
|
||||
Namespace string
|
||||
|
||||
// Repo represents the chart repository
|
||||
Repo struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// Values represents data to marshal into a values.yaml for helm.
|
||||
Values interface{} `cue:"{...}"`
|
||||
|
||||
// Chart represents the derived HelmChart for inclusion in the BuildPlan
|
||||
// Output field value. The default HelmChart field values are derived from
|
||||
// other Helm field values and should be sufficient for most use cases.
|
||||
Chart core.HelmChart
|
||||
|
||||
// EnableKustomizePostProcessor processes helm output with kustomize if true.
|
||||
EnableKustomizePostProcessor bool `cue:"true | *false"`
|
||||
|
||||
// KustomizeFiles represents additional files to include in a Kustomization
|
||||
// resources list. Useful to patch helm output. The implementation is a
|
||||
// struct with filename keys and structs as values. Holos encodes the struct
|
||||
// value to yaml then writes the result to the filename key. Component
|
||||
// authors may then reference the filename in the kustomization.yaml resources
|
||||
// or patches lists.
|
||||
// Requires EnableKustomizePostProcessor: true.
|
||||
KustomizeFiles map[string]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// KustomizePatches represents patches to apply to the helm output. Requires
|
||||
// EnableKustomizePostProcessor: true.
|
||||
KustomizePatches map[core.InternalLabel]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// KustomizeResources represents additional resources files to include in the
|
||||
// kustomize resources list.
|
||||
KustomizeResources map[string]any `cue:"{[string]: {...}}"`
|
||||
}
|
||||
|
||||
// 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
|
||||
// across all Components.
|
||||
type ArgoConfig struct {
|
||||
// Enabled causes holos to render an ArgoCD Application resource for GitOps if true.
|
||||
Enabled bool `cue:"true | *false"`
|
||||
// ClusterName represents the cluster within the platform the Application
|
||||
// resource is intended for.
|
||||
ClusterName string
|
||||
// DeployRoot represents the path from the git repository root to the `deploy`
|
||||
// rendering output directory. Used as a prefix for the
|
||||
// Application.spec.source.path field.
|
||||
DeployRoot string `cue:"string | *\".\""`
|
||||
// RepoURL represents the value passed to the Application.spec.source.repoURL
|
||||
// field.
|
||||
RepoURL string
|
||||
// TargetRevision represents the value passed to the
|
||||
// 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.
|
||||
type Cluster struct {
|
||||
// Name represents the cluster name, for example "east1", "west1", or
|
||||
// "management".
|
||||
Name string `json:"name"`
|
||||
// Primary represents if the cluster is marked as the primary among a set of
|
||||
// candidate clusters. Useful for promotion of database leaders.
|
||||
Primary bool `json:"primary" cue:"true | *false"`
|
||||
}
|
||||
|
||||
// Fleet represents a named collection of similarly configured Clusters. Useful
|
||||
// to segregate workload clusters from their management cluster.
|
||||
type Fleet struct {
|
||||
Name string `json:"name"`
|
||||
// Clusters represents a mapping of Clusters by their name.
|
||||
Clusters map[string]Cluster `json:"clusters" cue:"{[Name=_]: name: Name}"`
|
||||
}
|
||||
|
||||
// StandardFleets represents the standard set of Clusters in a Platform
|
||||
// segmented into Fleets by their purpose. The management Fleet contains a
|
||||
// single Cluster, for example a GKE autopilot cluster with no workloads
|
||||
// deployed for reliability and cost efficiency. The workload Fleet contains
|
||||
// all other Clusters which contain workloads and sync Secrets from the
|
||||
// management cluster.
|
||||
type StandardFleets struct {
|
||||
// Workload represents a Fleet of zero or more workload Clusters.
|
||||
Workload Fleet `json:"workload" cue:"{name: \"workload\"}"`
|
||||
// Management represents a Fleet with one Cluster named management.
|
||||
Management Fleet `json:"management" cue:"{name: \"management\"}"`
|
||||
}
|
||||
|
||||
// Platform is a convenience structure to produce a core Platform specification
|
||||
// value in the Output field. Useful to collect components at the root of the
|
||||
// Platform configuration tree as a struct, which are automatically converted
|
||||
// into a list for the core Platform spec output.
|
||||
type Platform struct {
|
||||
// Name represents the Platform name.
|
||||
Name string `cue:"string | *\"holos\""`
|
||||
// Components is a structured map of components to manage by their name.
|
||||
Components map[string]core.PlatformSpecComponent
|
||||
// Model represents the Platform model holos gets from from the
|
||||
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
|
||||
Model structpb.Struct `cue:"{...}"`
|
||||
// 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\""`
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
// Package v1alpha3 contains CUE definitions intended as convenience wrappers
|
||||
// around the core data types defined in package core. The purpose of these
|
||||
// wrappers is to make life easier for platform engineers by reducing boiler
|
||||
// plate code and generating component build plans in a consistent manner.
|
||||
package v1alpha3
|
||||
|
||||
import core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
|
||||
//go:generate ../../../hack/gendoc
|
||||
|
||||
// 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 chart name.
|
||||
Name string
|
||||
// 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 `cue:"{...}"`
|
||||
|
||||
// Repo represents the chart repository
|
||||
Repo struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// Values represents data to marshal into a values.yaml for helm.
|
||||
Values interface{} `cue:"{...}"`
|
||||
|
||||
// Chart represents the derived HelmChart for inclusion in the BuildPlan
|
||||
// Output field value. The default HelmChart field values are derived from
|
||||
// other Helm field values and should be sufficient for most use cases.
|
||||
Chart core.HelmChart
|
||||
|
||||
// EnableKustomizePostProcessor processes helm output with kustomize if true.
|
||||
EnableKustomizePostProcessor bool `cue:"true | *false"`
|
||||
|
||||
// KustomizeFiles represents additional files to include in a Kustomization
|
||||
// resources list. Useful to patch helm output. The implementation is a
|
||||
// struct with filename keys and structs as values. Holos encodes the struct
|
||||
// value to yaml then writes the result to the filename key. Component
|
||||
// authors may then reference the filename in the kustomization.yaml resources
|
||||
// or patches lists.
|
||||
// Requires EnableKustomizePostProcessor: true.
|
||||
KustomizeFiles map[string]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// KustomizePatches represents patches to apply to the helm output. Requires
|
||||
// EnableKustomizePostProcessor: true.
|
||||
KustomizePatches map[core.InternalLabel]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// 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
|
||||
|
||||
// ArgoConfig represents the ArgoCD GitOps configuration for a Component.
|
||||
// Useful to define once at the root of the Platform configuration and reuse
|
||||
// across all Components.
|
||||
type ArgoConfig struct {
|
||||
// Enabled causes holos to render an ArgoCD Application resource for GitOps if true.
|
||||
Enabled bool `cue:"true | *false"`
|
||||
// ClusterName represents the cluster within the platform the Application
|
||||
// resource is intended for.
|
||||
ClusterName string
|
||||
// DeployRoot represents the path from the git repository root to the `deploy`
|
||||
// rendering output directory. Used as a prefix for the
|
||||
// Application.spec.source.path field.
|
||||
DeployRoot string `cue:"string | *\".\""`
|
||||
// RepoURL represents the value passed to the Application.spec.source.repoURL
|
||||
// field.
|
||||
RepoURL string
|
||||
// TargetRevision represents the value passed to the
|
||||
// Application.spec.source.targetRevision field. Defaults to the branch named
|
||||
// main.
|
||||
TargetRevision string `cue:"string | *\"main\""`
|
||||
}
|
||||
5
doc/md/api.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# API Reference
|
||||
|
||||
<DocCardList />
|
||||
5
doc/md/api/author.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Author API
|
||||
|
||||
<DocCardList />
|
||||
213
doc/md/api/author/v1alpha3.md
Normal file
@@ -0,0 +1,213 @@
|
||||
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
|
||||
|
||||
# v1alpha3
|
||||
|
||||
```go
|
||||
import "github.com/holos-run/holos/api/author/v1alpha3"
|
||||
```
|
||||
|
||||
Package v1alpha3 contains CUE definitions intended as convenience wrappers around the core data types defined in package core. The purpose of these wrappers is to make life easier for platform engineers by reducing boiler plate code and generating component build plans in a consistent manner.
|
||||
|
||||
## Index
|
||||
|
||||
- [type ArgoConfig](<#ArgoConfig>)
|
||||
- [type Cluster](<#Cluster>)
|
||||
- [type ComponentFields](<#ComponentFields>)
|
||||
- [type Fleet](<#Fleet>)
|
||||
- [type Helm](<#Helm>)
|
||||
- [type Kubernetes](<#Kubernetes>)
|
||||
- [type Kustomize](<#Kustomize>)
|
||||
- [type Platform](<#Platform>)
|
||||
- [type StandardFleets](<#StandardFleets>)
|
||||
|
||||
|
||||
<a name="ArgoConfig"></a>
|
||||
## type ArgoConfig {#ArgoConfig}
|
||||
|
||||
ArgoConfig represents the ArgoCD GitOps configuration for a Component. Useful to define once at the root of the Platform configuration and reuse across all Components.
|
||||
|
||||
```go
|
||||
type ArgoConfig struct {
|
||||
// Enabled causes holos to render an ArgoCD Application resource for GitOps if true.
|
||||
Enabled bool `cue:"true | *false"`
|
||||
// ClusterName represents the cluster within the platform the Application
|
||||
// resource is intended for.
|
||||
ClusterName string
|
||||
// DeployRoot represents the path from the git repository root to the `deploy`
|
||||
// rendering output directory. Used as a prefix for the
|
||||
// Application.spec.source.path field.
|
||||
DeployRoot string `cue:"string | *\".\""`
|
||||
// RepoURL represents the value passed to the Application.spec.source.repoURL
|
||||
// field.
|
||||
RepoURL string
|
||||
// TargetRevision represents the value passed to the
|
||||
// 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\""`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Cluster"></a>
|
||||
## type Cluster {#Cluster}
|
||||
|
||||
Cluster represents a cluster managed by the Platform.
|
||||
|
||||
```go
|
||||
type Cluster struct {
|
||||
// Name represents the cluster name, for example "east1", "west1", or
|
||||
// "management".
|
||||
Name string `json:"name"`
|
||||
// Primary represents if the cluster is marked as the primary among a set of
|
||||
// candidate clusters. Useful for promotion of database leaders.
|
||||
Primary bool `json:"primary" cue:"true | *false"`
|
||||
}
|
||||
```
|
||||
|
||||
<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}
|
||||
|
||||
Fleet represents a named collection of similarly configured Clusters. Useful to segregate workload clusters from their management cluster.
|
||||
|
||||
```go
|
||||
type Fleet struct {
|
||||
Name string `json:"name"`
|
||||
// Clusters represents a mapping of Clusters by their name.
|
||||
Clusters map[string]Cluster `json:"clusters" cue:"{[Name=_]: name: Name}"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Helm"></a>
|
||||
## type Helm {#Helm}
|
||||
|
||||
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.
|
||||
|
||||
```go
|
||||
type Helm struct {
|
||||
ComponentFields `json:",inline"`
|
||||
|
||||
// Version represents the chart version.
|
||||
Version string
|
||||
// Namespace represents the helm namespace option when rendering the chart.
|
||||
Namespace string
|
||||
|
||||
// Repo represents the chart repository
|
||||
Repo struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// Values represents data to marshal into a values.yaml for helm.
|
||||
Values interface{} `cue:"{...}"`
|
||||
|
||||
// Chart represents the derived HelmChart for inclusion in the BuildPlan
|
||||
// Output field value. The default HelmChart field values are derived from
|
||||
// other Helm field values and should be sufficient for most use cases.
|
||||
Chart core.HelmChart
|
||||
|
||||
// EnableKustomizePostProcessor processes helm output with kustomize if true.
|
||||
EnableKustomizePostProcessor bool `cue:"true | *false"`
|
||||
|
||||
// KustomizeFiles represents additional files to include in a Kustomization
|
||||
// resources list. Useful to patch helm output. The implementation is a
|
||||
// struct with filename keys and structs as values. Holos encodes the struct
|
||||
// value to yaml then writes the result to the filename key. Component
|
||||
// authors may then reference the filename in the kustomization.yaml resources
|
||||
// or patches lists.
|
||||
// Requires EnableKustomizePostProcessor: true.
|
||||
KustomizeFiles map[string]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// KustomizePatches represents patches to apply to the helm output. Requires
|
||||
// EnableKustomizePostProcessor: true.
|
||||
KustomizePatches map[core.InternalLabel]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// KustomizeResources represents additional resources files to include in the
|
||||
// kustomize resources list.
|
||||
KustomizeResources map[string]any `cue:"{[string]: {...}}"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Kubernetes"></a>
|
||||
## type Kubernetes {#Kubernetes}
|
||||
|
||||
Kubernetes provides a BuildPlan via the Output field which contains inline API Objects provided directly from CUE.
|
||||
|
||||
```go
|
||||
type Kubernetes struct {
|
||||
ComponentFields `json:",inline"`
|
||||
// Objects represents the kubernetes api objects for the Component.
|
||||
Objects core.KubernetesObjects
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Kustomize"></a>
|
||||
## type Kustomize {#Kustomize}
|
||||
|
||||
Kustomize provides a BuildPlan via the Output field which contains one KustomizeBuild from package core.
|
||||
|
||||
```go
|
||||
type Kustomize struct {
|
||||
ComponentFields `json:",inline"`
|
||||
// Kustomization represents the kustomize build plan for holos to render.
|
||||
Kustomization core.KustomizeBuild
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Platform"></a>
|
||||
## type Platform {#Platform}
|
||||
|
||||
Platform is a convenience structure to produce a core Platform specification value in the Output field. Useful to collect components at the root of the Platform configuration tree as a struct, which are automatically converted into a list for the core Platform spec output.
|
||||
|
||||
```go
|
||||
type Platform struct {
|
||||
// Name represents the Platform name.
|
||||
Name string `cue:"string | *\"holos\""`
|
||||
// Components is a structured map of components to manage by their name.
|
||||
Components map[string]core.PlatformSpecComponent
|
||||
// Model represents the Platform model holos gets from from the
|
||||
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
|
||||
Model structpb.Struct `cue:"{...}"`
|
||||
// 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\""`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="StandardFleets"></a>
|
||||
## type StandardFleets {#StandardFleets}
|
||||
|
||||
StandardFleets represents the standard set of Clusters in a Platform segmented into Fleets by their purpose. The management Fleet contains a single Cluster, for example a GKE autopilot cluster with no workloads deployed for reliability and cost efficiency. The workload Fleet contains all other Clusters which contain workloads and sync Secrets from the management cluster.
|
||||
|
||||
```go
|
||||
type StandardFleets struct {
|
||||
// Workload represents a Fleet of zero or more workload Clusters.
|
||||
Workload Fleet `json:"workload" cue:"{name: \"workload\"}"`
|
||||
// Management represents a Fleet with one Cluster named management.
|
||||
Management Fleet `json:"management" cue:"{name: \"management\"}"`
|
||||
}
|
||||
```
|
||||
|
||||
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)
|
||||
5
doc/md/api/core.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Core API
|
||||
|
||||
<DocCardList />
|
||||
@@ -1,3 +0,0 @@
|
||||
# Core API
|
||||
|
||||
- [v1alpha2](v1alpha2)
|
||||
@@ -1,101 +0,0 @@
|
||||
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
|
||||
|
||||
# v1alpha3
|
||||
|
||||
```go
|
||||
import "github.com/holos-run/holos/api/schema/v1alpha3"
|
||||
```
|
||||
|
||||
Package v1alpha3 contains CUE definitions intended as convenience wrappers around the core data types defined in package core. The purpose of these wrappers is to make life easier for platform engineers by reducing boiler plate code and generating component build plans in a consistent manner.
|
||||
|
||||
## Index
|
||||
|
||||
- [type ArgoConfig](<#ArgoConfig>)
|
||||
- [type Helm](<#Helm>)
|
||||
|
||||
|
||||
<a name="ArgoConfig"></a>
|
||||
## type ArgoConfig {#ArgoConfig}
|
||||
|
||||
ArgoConfig represents the ArgoCD GitOps configuration for a Component. Useful to define once at the root of the Platform configuration and reuse across all Components.
|
||||
|
||||
```go
|
||||
type ArgoConfig struct {
|
||||
// Enabled causes holos to render an ArgoCD Application resource for GitOps if true.
|
||||
Enabled bool `cue:"true | *false"`
|
||||
// ClusterName represents the cluster within the platform the Application
|
||||
// resource is intended for.
|
||||
ClusterName string
|
||||
// DeployRoot represents the path from the git repository root to the `deploy`
|
||||
// rendering output directory. Used as a prefix for the
|
||||
// Application.spec.source.path field.
|
||||
DeployRoot string `cue:"string | *\".\""`
|
||||
// RepoURL represents the value passed to the Application.spec.source.repoURL
|
||||
// field.
|
||||
RepoURL string
|
||||
// TargetRevision represents the value passed to the
|
||||
// Application.spec.source.targetRevision field. Defaults to the branch named
|
||||
// main.
|
||||
TargetRevision string `cue:"string | *\"main\""`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Helm"></a>
|
||||
## type Helm {#Helm}
|
||||
|
||||
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.
|
||||
|
||||
```go
|
||||
type Helm struct {
|
||||
// Name represents the chart name.
|
||||
Name string
|
||||
// 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 `cue:"{...}"`
|
||||
|
||||
// Repo represents the chart repository
|
||||
Repo struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// Values represents data to marshal into a values.yaml for helm.
|
||||
Values interface{} `cue:"{...}"`
|
||||
|
||||
// Chart represents the derived HelmChart for inclusion in the BuildPlan
|
||||
// Output field value. The default HelmChart field values are derived from
|
||||
// other Helm field values and should be sufficient for most use cases.
|
||||
Chart core.HelmChart
|
||||
|
||||
// EnableKustomizePostProcessor processes helm output with kustomize if true.
|
||||
EnableKustomizePostProcessor bool `cue:"true | *false"`
|
||||
|
||||
// KustomizeFiles represents additional files to include in a Kustomization
|
||||
// resources list. Useful to patch helm output. The implementation is a
|
||||
// struct with filename keys and structs as values. Holos encodes the struct
|
||||
// value to yaml then writes the result to the filename key. Component
|
||||
// authors may then reference the filename in the kustomization.yaml resources
|
||||
// or patches lists.
|
||||
// Requires EnableKustomizePostProcessor: true.
|
||||
KustomizeFiles map[string]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// KustomizePatches represents patches to apply to the helm output. Requires
|
||||
// EnableKustomizePostProcessor: true.
|
||||
KustomizePatches map[core.InternalLabel]any `cue:"{[string]: {...}}"`
|
||||
|
||||
// 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
|
||||
}
|
||||
```
|
||||
|
||||
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)
|
||||
724
doc/md/archive/guides/2024-09-15-quickstart.mdx
Normal file
@@ -0,0 +1,724 @@
|
||||
---
|
||||
description: Try Holos with this quick start guide.
|
||||
slug: /archive/2024-09-15-quickstart
|
||||
sidebar_position: 100
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Quickstart
|
||||
|
||||
In this guide, you'll experience how Holos makes the process of operating a
|
||||
Platform safer, easier, and more consistent. We'll use Holos to manage a
|
||||
vendor-provided Helm chart as a Component. Next, we'll mix in our own custom
|
||||
resources to manage the Component with GitOps. Finally, you'll see how Holos
|
||||
makes it safer and easier to maintain software over time by surfacing the exact
|
||||
changes that will be applied when upgrading the vendor's chart to a new version,
|
||||
before they are actually made.
|
||||
|
||||
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 Holos Components that
|
||||
wrap upstream Helm charts.
|
||||
|
||||
Optionally, if you'd like to apply the rendered manifests to a real Cluster,
|
||||
first complete the [Local Cluster Guide](/docs/guides/local-cluster).
|
||||
|
||||
## Install Holos
|
||||
|
||||
Install Holos with the following command or other methods listed on the
|
||||
[Installation](/docs/install/) page.
|
||||
|
||||
```bash
|
||||
go install github.com/holos-run/holos/cmd/holos@latest
|
||||
```
|
||||
|
||||
## 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 holos-quickstart
|
||||
cd holos-quickstart
|
||||
git init
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
Initialized empty Git repository in /holos-quickstart/.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}
|
||||
|
||||
Generate the Platform code in the repository root. A Platform refers to the
|
||||
entire set of software holistically integrated to provide a software development
|
||||
platform for your organization. In this guide, the Platform will include a
|
||||
single Component to demonstrate how the concepts fit together.
|
||||
|
||||
```bash
|
||||
holos generate platform quickstart
|
||||
```
|
||||
|
||||
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 quickstart - $(holos --version)"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main (root-commit) 0b17b7f] holos generate platform quickstart
|
||||
213 files changed, 72349 insertions(+)
|
||||
...
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Generate a Component {#generate-component}
|
||||
|
||||
The platform you generated is currently empty. Run the following command to
|
||||
generate the CUE code that defines a Helm Component.
|
||||
|
||||
<Tabs groupId="gen-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component podinfo --component-version 6.6.1
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The --component-version 6.6.1 flag intentionally installs an older release.
|
||||
You'll see how Holos assists with software upgrades later in this guide.
|
||||
|
||||
The generate component command creates two files: a leaf file,
|
||||
`components/podinfo/podinfo.gen.cue`, and a root file, `podinfo.gen.cue`. Holos
|
||||
leverages the fact that [order is
|
||||
irrelevant](https://cuelang.org/docs/tour/basics/order-irrelevance/) in CUE to
|
||||
register the component with the Platform by adding a file to the root of the Git
|
||||
repository. The second file defines the component in the leaf component
|
||||
directory.
|
||||
|
||||
<Tabs groupId="podinfo-files">
|
||||
<TabItem value="components/podinfo/podinfo.gen.cue" label="Leaf">
|
||||
`components/podinfo/podinfo.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "podinfo"
|
||||
Version: "6.6.1"
|
||||
Namespace: "default"
|
||||
|
||||
Repo: name: "podinfo"
|
||||
Repo: url: "https://stefanprodan.github.io/podinfo"
|
||||
|
||||
Values: {}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="podinfo.gen.cue" label="Root">
|
||||
`podinfo.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Manage podinfo on workload clusters only
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/podinfo": {
|
||||
path: "components/podinfo"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
In this example, we provide the minimal information needed to manage the Helm
|
||||
chart: the name, version, Kubernetes namespace for deployment, and the chart
|
||||
repository location.
|
||||
|
||||
This chart deploys cleanly without any values provided, but we include an empty
|
||||
Values struct to show how Holos improves consistency and safety in Helm by
|
||||
leveraging the strong type-checking in CUE. You can safely pass shared values,
|
||||
such as the organization’s domain name, to all Components across all clusters in
|
||||
the Platform by defining them at the root of the configuration.
|
||||
|
||||
Commit the generated component config to the repository.
|
||||
|
||||
<Tabs groupId="commit-component">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos generate component podinfo - $(holos --version)"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main cc0e90c] holos generate component podinfo
|
||||
2 files changed, 24 insertions(+)
|
||||
create mode 100644 components/podinfo/podinfo.gen.cue
|
||||
create mode 100644 podinfo.gen.cue
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Render the Component
|
||||
|
||||
You can render individual components without adding them to a Platform, which is
|
||||
helpful when developing a new component.
|
||||
|
||||
<Tabs groupId="render-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render component ./components/podinfo --cluster-name=default
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
cached
|
||||
rendered podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
First, the command caches the Helm chart locally to speed up subsequent
|
||||
renderings. Then, the command runs Helm to produce the output and writes it into
|
||||
the deploy directory.
|
||||
|
||||
<Tabs groupId="tree-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
└── default
|
||||
└── components
|
||||
└── podinfo
|
||||
└── podinfo.gen.yaml
|
||||
|
||||
5 directories, 1 file
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The component deploys to one cluster named `default`. In practice, the same
|
||||
component is often deployed to multiple clusters, such as `east` and `west` to
|
||||
provide redundancy and increase availability.
|
||||
|
||||
:::tip
|
||||
This example is equivalent to running `helm template` on the chart and saving
|
||||
the output to a file. Holos simplifies this task, making it safer and more
|
||||
consistent when managing many charts.
|
||||
:::
|
||||
|
||||
## Mix in an ArgoCD Application
|
||||
|
||||
We've seen how Holos works with Helm, but we haven't yet explored how Holos
|
||||
makes it easier to consistently and safely manage all of the software in a
|
||||
Platform.
|
||||
|
||||
Holos allows you to easily mix in resources that differentiate your Platform.
|
||||
We'll use this feature to mix in an ArgoCD [Application][application] to manage
|
||||
the podinfo Component with GitOps. We'll define this configuration in a way that
|
||||
can be automatically and consistently reused across all future Components added
|
||||
to the Platform.
|
||||
|
||||
Create a new file named `argocd.cue` in the root of your Git repository with the
|
||||
following contents:
|
||||
|
||||
<Tabs groupId="argocd-config">
|
||||
<TabItem value="command" label="argocd.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
RepoURL: "https://github.com/holos-run/holos-quickstart-guide"
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
If you plan to apply the rendered output to a real cluster, change the
|
||||
`example.com` RepoURL to the URL of the Git repository you created in this
|
||||
guide. You don't need to change the example if you're just exploring Holos by
|
||||
inspecting the rendered output without applying it to a live cluster.
|
||||
:::
|
||||
|
||||
With this file in place, render the component again.
|
||||
|
||||
<Tabs groupId="render-podinfo-argocd">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render component ./components/podinfo --cluster-name=default
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
wrote deploy file
|
||||
rendered gitops/podinfo
|
||||
rendered podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Holos uses the locally cached chart to improve performance and reliability. It
|
||||
then renders the Helm template output along with an ArgoCD Application resource
|
||||
for GitOps.
|
||||
|
||||
:::tip
|
||||
By defining the ArgoCD configuration at the root, we again take advantage of the
|
||||
fact that [order is
|
||||
irrelevant](https://cuelang.org/docs/tour/basics/order-irrelevance/) in CUE.
|
||||
:::
|
||||
|
||||
Defining the configuration at the root ensures all future leaf Components take
|
||||
the ArgoCD configuration and render an Application manifest for GitOps
|
||||
management.
|
||||
|
||||
<Tabs groupId="tree-podinfo-argocd">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
└── default
|
||||
├── components
|
||||
│ └── podinfo
|
||||
│ └── podinfo.gen.yaml
|
||||
└── gitops
|
||||
└── podinfo.application.gen.yaml
|
||||
|
||||
6 directories, 2 files
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Notice the new `podinfo.application.gen.yaml` file created by enabling ArgoCD in
|
||||
the Helm component. The Application resource in the file looks like this:
|
||||
|
||||
<Tabs groupId="podinfo-application">
|
||||
<TabItem value="file" label="podinfo.application.gen.yaml">
|
||||
```yaml showLineNumbers
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
path: ./deploy/clusters/default/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
Holos generates a similar Application resource for every additional Component
|
||||
added to your Platform.
|
||||
:::
|
||||
|
||||
Finally, add and commit the results to your Platform's Git repository.
|
||||
|
||||
<Tabs groupId="commit-argo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos render component ./components/podinfo --cluster-name=default"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main f95cef1] holos render component ./components/podinfo --cluster-name=default
|
||||
3 files changed, 134 insertions(+)
|
||||
create mode 100644 argocd.cue
|
||||
create mode 100644 deploy/clusters/default/components/podinfo/podinfo.gen.yaml
|
||||
create mode 100644 deploy/clusters/default/gitops/podinfo.application.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
In this section, we learned how Holos simplifies mixing resources into
|
||||
Components, like an ArgoCD Application. Holos ensures consistency by managing an
|
||||
Application resource for every Component added to the Platform through the
|
||||
configuration you define in `argocd.cue` at the root of the repository.
|
||||
|
||||
## Define Workload Clusters {#workload-clusters}
|
||||
|
||||
We've generated a Component to manage podinfo and integrated it with our
|
||||
Platform, but rendering the Platform doesn't render podinfo. Podinfo isn't
|
||||
rendered because we haven't assigned any Clusters to the workload Fleet.
|
||||
|
||||
Define two new clusters, `east` and `west`, and assign them to the workload
|
||||
Fleet. Create a new file named `clusters.cue` in the root of your Git repository
|
||||
with the following contents:
|
||||
|
||||
<Tabs groupId="clusters">
|
||||
<TabItem value="clusters.cue" label="clusters.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Define two workload clusters for disaster recovery.
|
||||
#Fleets: workload: clusters: {
|
||||
// In CUE _ indicates values are defined elsewhere.
|
||||
east: _
|
||||
west: _
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This example shows how Holos simplifies configuring multiple clusters with
|
||||
similar configuration by grouping them into a Fleet.
|
||||
|
||||
:::tip
|
||||
Fleets help segment a group of Clusters into one leader and multiple followers
|
||||
by designating one cluster as the primary. Holos makes it safer, easier, and
|
||||
more consistent to reconfigure which cluster is the primary. The primary can be
|
||||
set to automatically restore persistent data from backups, while non-primary
|
||||
clusters can be configured to automatically replicate from the primary.
|
||||
|
||||
Automatic database backup, restore, and streaming replication is an advanced
|
||||
topic enabled by Cloud Native PG and CUE. Check back for a guide on this and
|
||||
other Day 2 operations topics.
|
||||
:::
|
||||
|
||||
## Render the Platform {#render-platform}
|
||||
|
||||
Render the Platform to render the podinfo Component for each of the workload
|
||||
clusters.
|
||||
|
||||
<Tabs groupId="render-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered components/podinfo for cluster west in 99.480792ms
|
||||
rendered components/podinfo for cluster east in 99.882667ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The render platform command iterates over every Cluster in the Fleet and renders
|
||||
each Component assigned to the Fleet. Notice the two additional subdirectories
|
||||
created under the deploy directory, one for each cluster: `east` and `west`.
|
||||
|
||||
<Tabs groupId="tree-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
├── default
|
||||
│ ├── components
|
||||
│ │ └── podinfo
|
||||
│ │ └── podinfo.gen.yaml
|
||||
│ └── gitops
|
||||
│ └── podinfo.application.gen.yaml
|
||||
# highlight-next-line
|
||||
├── east
|
||||
│ ├── components
|
||||
│ │ └── podinfo
|
||||
│ │ └── podinfo.gen.yaml
|
||||
│ └── gitops
|
||||
│ └── podinfo.application.gen.yaml
|
||||
# highlight-next-line
|
||||
└── west
|
||||
├── components
|
||||
│ └── podinfo
|
||||
│ └── podinfo.gen.yaml
|
||||
└── gitops
|
||||
└── podinfo.application.gen.yaml
|
||||
|
||||
14 directories, 6 files
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Holos ensures consistency and safety by defining the ArgoCD Application once,
|
||||
with strong type checking, at the configuration root.
|
||||
|
||||
New Application resources are automatically generated for the `east` and `west`
|
||||
workload Clusters.
|
||||
|
||||
<Tabs groupId="applications">
|
||||
<TabItem value="east" label="east">
|
||||
`deploy/clusters/east/gitops/podinfo.application.gen.yaml`
|
||||
```yaml showLineNumbers
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
# highlight-next-line
|
||||
path: ./deploy/clusters/east/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="west" label="west">
|
||||
`deploy/clusters/west/gitops/podinfo.application.gen.yaml`
|
||||
```yaml showLineNumbers
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
# highlight-next-line
|
||||
path: ./deploy/clusters/west/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="default" label="default">
|
||||
`deploy/clusters/default/gitops/podinfo.application.gen.yaml`
|
||||
```yaml showLineNumbers
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
# highlight-next-line
|
||||
path: ./deploy/clusters/default/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Add and commit the rendered Platform and workload Clusters.
|
||||
|
||||
<Tabs groupId="commit-render-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos render platform ./platform - $(holos --version)"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main 5aebcf5] holos render platform ./platform - 0.93.2
|
||||
5 files changed, 263 insertions(+)
|
||||
create mode 100644 clusters.cue
|
||||
create mode 100644 deploy/clusters/east/components/podinfo/podinfo.gen.yaml
|
||||
create mode 100644 deploy/clusters/east/gitops/podinfo.application.gen.yaml
|
||||
create mode 100644 deploy/clusters/west/components/podinfo/podinfo.gen.yaml
|
||||
create mode 100644 deploy/clusters/west/gitops/podinfo.application.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Upgrade a Helm Chart
|
||||
|
||||
Holos is designed to ease the burden of Day 2 operations. With Holos, upgrading
|
||||
software, integrating new software, and making safe platform-wide configuration
|
||||
changes become easier.
|
||||
|
||||
Let's upgrade the podinfo Component to see how this works in practice. First,
|
||||
update the Component version field to the latest upstream Helm chart version.
|
||||
|
||||
<Tabs groupId="gen-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component podinfo --component-version 6.6.2
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Remove the cached chart version.
|
||||
|
||||
<Tabs groupId="gen-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
rm -rf components/podinfo/vendor
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Now re-render the Platform.
|
||||
|
||||
<Tabs groupId="render-platform2">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered components/podinfo for cluster east in 327.10475ms
|
||||
rendered components/podinfo for cluster west in 327.796541ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Notice we're still using the upstream chart without modifying it. The Holos
|
||||
component wraps around the chart to mix in additional resources and integrate
|
||||
the component with the broader Platform.
|
||||
|
||||
## Visualize the Changes
|
||||
|
||||
Holos makes it easier to see exactly what changes are made and which resources
|
||||
will be applied to the API server. By design, Holos operates on local files,
|
||||
leaving the task of applying them to ecosystem tools like `kubectl` and ArgoCD.
|
||||
This allows platform operators to inspect changes during code review, or before
|
||||
committing the change at all.
|
||||
|
||||
For example, using `git diff`, we see that the only functional change when
|
||||
upgrading this Helm chart is the deployment of a new container image tag to each
|
||||
cluster. Additionally, we can roll out this change gradually by applying it to
|
||||
the east cluster first, then to the west cluster, limiting the potential blast
|
||||
radius of a problematic change.
|
||||
|
||||
<Tabs groupId="git-diff">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git diff deploy/clusters/east
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```diff showLineNumbers
|
||||
diff --git a/deploy/clusters/east/components/podinfo/podinfo.gen.yaml b/deploy/clusters/east/components/podinfo/podinfo.gen.yaml
|
||||
index 7cc3332..8c1647d 100644
|
||||
--- a/deploy/clusters/east/components/podinfo/podinfo.gen.yaml
|
||||
+++ b/deploy/clusters/east/components/podinfo/podinfo.gen.yaml
|
||||
@@ -5,9 +5,9 @@ kind: Service
|
||||
metadata:
|
||||
name: podinfo
|
||||
labels:
|
||||
- helm.sh/chart: podinfo-6.6.1
|
||||
+ helm.sh/chart: podinfo-6.6.2
|
||||
app.kubernetes.io/name: podinfo
|
||||
- app.kubernetes.io/version: "6.6.1"
|
||||
+ app.kubernetes.io/version: "6.6.2"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
type: ClusterIP
|
||||
@@ -29,9 +29,9 @@ kind: Deployment
|
||||
metadata:
|
||||
name: podinfo
|
||||
labels:
|
||||
- helm.sh/chart: podinfo-6.6.1
|
||||
+ helm.sh/chart: podinfo-6.6.2
|
||||
app.kubernetes.io/name: podinfo
|
||||
- app.kubernetes.io/version: "6.6.1"
|
||||
+ app.kubernetes.io/version: "6.6.2"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
replicas: 1
|
||||
@@ -53,7 +53,7 @@ spec:
|
||||
terminationGracePeriodSeconds: 30
|
||||
containers:
|
||||
- name: podinfo
|
||||
# highlight-next-line
|
||||
- image: "ghcr.io/stefanprodan/podinfo:6.6.1"
|
||||
# highlight-next-line
|
||||
+ image: "ghcr.io/stefanprodan/podinfo:6.6.2"
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- ./podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
Holos is designed to surface the _fully rendered_ manifests intended for the
|
||||
Kubernetes API server, making it easier to see and reason about platform-wide
|
||||
configuration changes.
|
||||
:::
|
||||
|
||||
## Recap {#recap}
|
||||
|
||||
In this quickstart guide, we learned how Holos makes it easier, safer, and more
|
||||
consistent to manage a Platform composed of multiple Clusters and upstream Helm
|
||||
charts.
|
||||
|
||||
We covered how to:
|
||||
|
||||
1. Generate a Git repository for the Platform config.
|
||||
2. Wrap the unmodified upstream podinfo Helm chart into a Component.
|
||||
3. Render an individual Component.
|
||||
4. Mix-in your Platform's unique resources to all Components. For example, ArgoCD Application resources.
|
||||
5. Define multiple similar, but not identical, workload clusters.
|
||||
6. Render the manifests for the entire Platform with the `holos render platform` command.
|
||||
7. Upgrade a Helm chart to the latest version as an important Day 2 task.
|
||||
8. Visualize and surface the details of planned changes Platform wide.
|
||||
|
||||
## Dive Deeper
|
||||
|
||||
If you'd like to dive deeper, check out the [Schema API][schema] and [Core
|
||||
API][core] reference docs. The main difference between the schema and core
|
||||
packages is that the schema is used by users to write refined CUE, while the
|
||||
core package is what the schema produces for `holos` to execute. Users rarely
|
||||
need to interact with the Core API when on the happy path, but can use the core
|
||||
package as an escape hatch when the happy path doesn't go where you want.
|
||||
|
||||
|
||||
[application]: https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/
|
||||
[schema]: /docs/api/author/v1alpha3/
|
||||
[core]: /docs/api/core/v1alpha3/
|
||||
106
doc/md/archive/guides/2024-09-17-manage-a-project.mdx
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
description: Self service platform resource management for project teams.
|
||||
slug: /archive/guides/2024-09-17-manage-a-project
|
||||
sidebar_position: 250
|
||||
---
|
||||
|
||||
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.
|
||||
|
Before Width: | Height: | Size: 934 KiB After Width: | Height: | Size: 934 KiB |
|
Before Width: | Height: | Size: 703 KiB After Width: | Height: | Size: 703 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1014 KiB After Width: | Height: | Size: 1014 KiB |
|
Before Width: | Height: | Size: 728 KiB After Width: | Height: | Size: 728 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1014 KiB After Width: | Height: | Size: 1014 KiB |
|
Before Width: | Height: | Size: 854 KiB After Width: | Height: | Size: 854 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
1862
doc/md/archive/guides/expose-a-service.mdx
Normal file
|
Before Width: | Height: | Size: 624 KiB After Width: | Height: | Size: 624 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
@@ -671,10 +671,10 @@ foundation of a software development platform that:
|
||||
|
||||
Dive deeper with the following resources that build on the foundation you have now.
|
||||
|
||||
1. Explore the [Rendering Process](/docs/design/rendering) in Holos.
|
||||
1. Explore the [Rendering Process](/docs/concepts#rendering) in Holos.
|
||||
2. Dive deeper into the [Platform Manifests](./platform-manifests) rendered in this guide.
|
||||
3. Deploy [ArgoCD](/docs/guides/argocd) onto the foundation you built.
|
||||
4. Deploy [Backstage](/docs/guides/backstage) as a portal to the integrated platform components.
|
||||
3. Deploy [ArgoCD](../argocd) onto the foundation you built.
|
||||
4. Deploy [Backstage](../backstage) as a portal to the integrated platform components.
|
||||
|
||||
## Clean-Up
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This document provides an example of how Holos uses CUE and Helm to unify and
|
||||
render the platform configuration. It refers to the manifests rendered in the
|
||||
[Try Holos Locally](/docs/guides/try-holos/) guide.
|
||||
Try Holos Locally guide.
|
||||
|
||||
Take a moment to review the manifests `holos` rendered to build the platform.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This document captures notes on locally developing Holos.
|
||||
|
||||
Follow the steps in [Try Holos Locally](/docs/guides/try-holos), but take care
|
||||
Follow the steps in [Try Holos Locally](../guides/try-holos), but take care
|
||||
to select `Develop` tabs when creating the k3d cluster so you have a local
|
||||
registry to push to.
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# Comparison with other tools
|
||||
|
||||
:::tip
|
||||
|
||||
Holos is designed to complement and improve, not replace, existing tools in the cloud native ecosystem.
|
||||
|
||||
:::
|
||||
|
||||
## Helm
|
||||
|
||||
### Chart Users
|
||||
|
||||
Describe how things are different when using an upstream helm chart.
|
||||
|
||||
### Chart Authors
|
||||
|
||||
Describe how things are different when writing a new helm chart.
|
||||
|
||||
## Kustomize
|
||||
|
||||
TODO
|
||||
|
||||
## ArgoCD
|
||||
|
||||
TODO
|
||||
|
||||
## Flux
|
||||
|
||||
TODO
|
||||
|
||||
## Timoni
|
||||
|
||||
| Aspect | Timoni | Holos | Comment |
|
||||
| -- | -- | -- | -- |
|
||||
| Language | CUE | CUE | Like Holos, Timoni is also built on CUE. |
|
||||
| Artifact | OCI Image | Plain YAML Files | The Holos Authors find plain files easier to work with and reason about than OCI images. |
|
||||
| Outputs to | OCI Image Repository | Local Git repository | Holos is designed for use with existing GitOps tools. |
|
||||
| Concept | Module | Component | A Timoni Module is analogous to a Holos Component. |
|
||||
| Concept | Bundle | Platform | A Timoni Bundle is somewhat similar, but smaller in scope to a Holos Platform. |
|
||||
|
||||
:::important
|
||||
|
||||
The Holos Authors are deeply grateful to Stefan and Timoni for the capability of
|
||||
importing Kubernetes custom resource definitions into CUE. Without this
|
||||
functionality, much of the Kubernetes ecosystem would be more difficult to
|
||||
manage in CUE and therefore in Holos.
|
||||
|
||||
:::
|
||||
|
||||
|
||||
## KubeVela
|
||||
|
||||
1. Also built on CUE.
|
||||
2. Intended to create an Application abstraction.
|
||||
3. Holos prioritizes composition over abstraction.
|
||||
4. An abstraction of an Application acts as a filter that removes all but the lowest common denominator functionality. The Holos Authors have found this filtering effect to create excessive friction for software developers.
|
||||
5. Holos focuses instead on composition to empower developers and platform engineers to leverage the unique features and functionality of their software and platform.
|
||||
|
||||
## Pulumi
|
||||
|
||||
TODO
|
||||
|
||||
## Jsonnet
|
||||
|
||||
TODO
|
||||
@@ -1,47 +0,0 @@
|
||||
# Rendering
|
||||
|
||||
:::tip
|
||||
|
||||
This document provides a brief overview of the rendering process, a core design
|
||||
element in Holos.
|
||||
|
||||
:::
|
||||
|
||||
Holos uses the Kubernetes resource model to manage configuration. The `holos`
|
||||
command line interface is the primary method you'll use to manage your platform.
|
||||
Holos uses CUE to provide a unified configuration model of the platform. This
|
||||
unified configuration is built up from components packaged with Helm, Kustomize,
|
||||
CUE, or any other tool that can produce Kubernetes resource manifests as output.
|
||||
|
||||
This process can be thought of as a data **rendering pipeline**. The key
|
||||
concept is that `holos` will always produce fully rendered output, but delegates
|
||||
the _application_ of the configuration to other tools like `kubectl apply`,
|
||||
ArgoCD, or Flux.
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: Figure 2 - Render Pipeline
|
||||
---
|
||||
graph LR
|
||||
PS[<a href="/docs/api/core/v1alpha2#PlatformSpec">PlatformSpec</a>]
|
||||
BP[<a href="/docs/api/core/v1alpha2#BuildPlan">BuildPlan</a>]
|
||||
HC[<a href="/docs/api/core/v1alpha2#HolosComponent">HolosComponent</a>]
|
||||
|
||||
H[<a href="/docs/api/core/v1alpha2#HelmChart">HelmChart</a>]
|
||||
K[<a href="/docs/api/core/v1alpha2#KustomizeBuild">KustomizeBuild</a>]
|
||||
O[<a href="/docs/api/core/v1alpha2#KubernetesObjects">KubernetesObjects</a>]
|
||||
|
||||
P[<a href="/docs/api/core/v1alpha2#Kustomize">Kustomize</a>]
|
||||
Y[Kubernetes <br>Resources]
|
||||
G[GitOps <br>Resource]
|
||||
|
||||
C[Kube API Server]
|
||||
|
||||
PS --> BP --> HC
|
||||
HC --> H --> P
|
||||
HC --> K --> P
|
||||
HC --> O --> P
|
||||
|
||||
P --> Y --> C
|
||||
P --> G --> C
|
||||
```
|
||||
24
doc/md/guides.md
Normal file
@@ -0,0 +1,24 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Guides
|
||||
|
||||
## Start with the [Quickstart] guide
|
||||
|
||||
The guides are organized as a progression. We'll use Holos to manage a
|
||||
fictional bank's platform, the Bank of Holos in each of the guides. In doing so
|
||||
we'll take the time to explain the foundational concepts of Holos.
|
||||
|
||||
1. [Quickstart] covers the foundational concepts of Holos.
|
||||
2. [Deploy a Service] explains how to deploy a containerized service using an
|
||||
existing Helm chart. This guide then explains how to deploy a similar service
|
||||
safely and consistently with CUE instead of Helm.
|
||||
3. [Change a Service] covers the day two task of making configuration changes to
|
||||
deployed services safely and consistently.
|
||||
|
||||
---
|
||||
|
||||
<DocCardList />
|
||||
|
||||
[Quickstart]: /docs/quickstart/
|
||||
[Deploy a Service]: /docs/guides/deploy-a-service/
|
||||
[Change a Service]: /docs/guides/change-a-service/
|
||||
11
doc/md/guides/change-a-service.mdx
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
description: Change a service on your platform.
|
||||
slug: /guides/change-a-service
|
||||
sidebar_position: 300
|
||||
---
|
||||
|
||||
# Change a Service
|
||||
|
||||
:::warning
|
||||
Under construction.
|
||||
:::
|
||||
11
doc/md/guides/deploy-a-service.mdx
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
description: Deploy a service on your platform.
|
||||
slug: /guides/deploy-a-service
|
||||
sidebar_position: 200
|
||||
---
|
||||
|
||||
# Deploy a Service
|
||||
|
||||
:::warning
|
||||
Under construction.
|
||||
:::
|
||||
BIN
doc/md/guides/img/bank-home.png
Normal file
|
After Width: | Height: | Size: 690 KiB |
277
doc/md/guides/local-cluster.mdx
Normal file
@@ -0,0 +1,277 @@
|
||||
---
|
||||
description: Build a local Cluster to use with these guides.
|
||||
slug: /guides/local-cluster
|
||||
sidebar_position: 999
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Local Cluster
|
||||
|
||||
In this guide we'll set up a local k3d cluster to apply and explore the
|
||||
configuration described in our other guides. After completing this guide you'll
|
||||
have a standard Kubernetes API server with proper DNS and TLS certificates.
|
||||
You'll be able to easily reset the cluster to a known good state to iterate on
|
||||
your own Platform.
|
||||
|
||||
The [Concepts](/docs/concepts) page defines capitalized terms such as Platform
|
||||
and Component.
|
||||
|
||||
## Reset the Cluster
|
||||
|
||||
If you've already followed this guide, reset the cluster by running the
|
||||
following commands. Skip this section if you're creating a cluster for the
|
||||
first time.
|
||||
|
||||
First, delete the cluster.
|
||||
|
||||
<Tabs groupId="k3d-cluster-delete">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
k3d cluster delete workload
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
INFO[0000] Deleting cluster 'workload'
|
||||
INFO[0000] Deleting cluster network 'k3d-workload'
|
||||
INFO[0000] Deleting 1 attached volumes...
|
||||
INFO[0000] Removing cluster details from default kubeconfig...
|
||||
INFO[0000] Removing standalone kubeconfig file (if there is one)...
|
||||
INFO[0000] Successfully deleted cluster workload!
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Then create the cluster again.
|
||||
|
||||
<Tabs groupId="k3d-cluster-create">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
k3d cluster create workload \
|
||||
--registry-use k3d-registry.holos.localhost:5100 \
|
||||
--port "443:443@loadbalancer" \
|
||||
--k3s-arg "--disable=traefik@server:0"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
INFO[0000] portmapping '443:443' targets the loadbalancer: defaulting to [servers:*:proxy agents:*:proxy]
|
||||
INFO[0000] Prep: Network
|
||||
INFO[0000] Created network 'k3d-workload'
|
||||
INFO[0000] Created image volume k3d-workload-images
|
||||
INFO[0000] Starting new tools node...
|
||||
INFO[0000] Starting node 'k3d-workload-tools'
|
||||
INFO[0001] Creating node 'k3d-workload-server-0'
|
||||
INFO[0001] Creating LoadBalancer 'k3d-workload-serverlb'
|
||||
INFO[0001] Using the k3d-tools node to gather environment information
|
||||
INFO[0001] HostIP: using network gateway 172.17.0.1 address
|
||||
INFO[0001] Starting cluster 'workload'
|
||||
INFO[0001] Starting servers...
|
||||
INFO[0001] Starting node 'k3d-workload-server-0'
|
||||
INFO[0003] All agents already running.
|
||||
INFO[0003] Starting helpers...
|
||||
INFO[0003] Starting node 'k3d-workload-serverlb'
|
||||
INFO[0009] Injecting records for hostAliases (incl. host.k3d.internal) and for 3 network members into CoreDNS configmap...
|
||||
INFO[0012] Cluster 'workload' created successfully!
|
||||
INFO[0012] You can now use it like this:
|
||||
kubectl cluster-info
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Finally, add your trusted certificate authority.
|
||||
|
||||
<Tabs groupId="apply-local-ca">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
kubectl apply --server-side=true -f "$(mkcert -CAROOT)/namespace.yaml"
|
||||
kubectl apply --server-side=true -n cert-manager -f "$(mkcert -CAROOT)/local-ca.yaml"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt showLineNumbers
|
||||
namespace/cert-manager serverside-applied
|
||||
secret/local-ca serverside-applied
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
You're back to the same state as the first time you completed this guide.
|
||||
|
||||
## 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 Holos components that wrap upstream Helm charts.
|
||||
3. [k3d](https://k3d.io/#installation) - to provide a k8s api server.
|
||||
4. [OrbStack](https://docs.orbstack.dev/install) or [Docker](https://docs.docker.com/get-docker/) - to use k3d.
|
||||
5. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to interact with the k8s api server.
|
||||
6. [mkcert](https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installation) - to make trusted TLS certificates.
|
||||
7. [jq](https://jqlang.github.io/jq/download/) - to fiddle with JSON output.
|
||||
|
||||
## Configure DNS {#configure-dns}
|
||||
|
||||
Configure your machine to resolve `*.holos.localhost` to your loopback
|
||||
interface. This is necessary for requests to reach the workload cluster. Save
|
||||
this script to a file and execute it.
|
||||
|
||||
```bash showLineNumbers
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
brew install dnsmasq
|
||||
|
||||
cat <<EOF >"$(brew --prefix)/etc/dnsmasq.d/holos.localhost.conf"
|
||||
# Refer to https://holos.run/docs/tutorial/local/k3d/
|
||||
address=/holos.localhost/127.0.0.1
|
||||
EOF
|
||||
|
||||
if [[ -r /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist ]]; then
|
||||
echo "dnsmasq already configured"
|
||||
else
|
||||
sudo cp "$(brew list dnsmasq | grep 'dnsmasq.plist$')" \
|
||||
/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl unload /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
dscacheutil -flushcache
|
||||
echo "dnsmasq configured"
|
||||
fi
|
||||
|
||||
sudo mkdir -p /etc/resolver
|
||||
sudo tee /etc/resolver/holos.localhost <<EOF
|
||||
domain holos.localhost
|
||||
nameserver 127.0.0.1
|
||||
EOF
|
||||
sudo killall -HUP mDNSResponder
|
||||
|
||||
echo "all done."
|
||||
```
|
||||
|
||||
## Create the Cluster {#create-the-cluster}
|
||||
|
||||
The Workload Cluster is where your applications and services will be deployed.
|
||||
In production this is usually an EKS, GKE, or AKS cluster.
|
||||
|
||||
:::tip
|
||||
|
||||
Holos supports all compliant Kubernetes clusters. Holos was developed and tested
|
||||
on GKE, EKS, Talos, k3s, and Kubeadm clusters.
|
||||
|
||||
:::
|
||||
|
||||
Create a local registry to speed up image builds and pulls.
|
||||
|
||||
```bash
|
||||
k3d registry create registry.holos.localhost --port 5100
|
||||
```
|
||||
|
||||
Create the workload cluster configured to use the local registry.
|
||||
|
||||
```bash
|
||||
k3d cluster create workload \
|
||||
--registry-use k3d-registry.holos.localhost:5100 \
|
||||
--port "443:443@loadbalancer" \
|
||||
--k3s-arg "--disable=traefik@server:0"
|
||||
```
|
||||
|
||||
Traefik is disabled because Istio provides the same functionality.
|
||||
|
||||
## Setup Root CA {#setup-root-ca}
|
||||
|
||||
Platforms most often use cert-manager to issue tls certificates. The browser
|
||||
and tools we're using need to trust these certificates to work together.
|
||||
Generate a local, trusted root certificate authority with the following script.
|
||||
|
||||
Admin access is necessary for `mkcert` to manage the certificate into your trust
|
||||
stores.
|
||||
|
||||
```bash
|
||||
sudo -v
|
||||
```
|
||||
|
||||
Manage the local CA and copy the CA key to the workload cluster so that cert
|
||||
manager can manage trusted certificates.
|
||||
|
||||
Save this script to a file and execute it to configure a trusted certificate
|
||||
authority.
|
||||
|
||||
```bash showLineNumbers
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
mkcert --install
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
# Create the local CA Secret with ca.crt, tls.crt, tls.key
|
||||
|
||||
mkdir local-ca
|
||||
cd local-ca
|
||||
CAROOT="$(mkcert -CAROOT)"
|
||||
cp -p "${CAROOT}/rootCA.pem" ca.crt
|
||||
cp -p "${CAROOT}/rootCA.pem" tls.crt
|
||||
cp -p "${CAROOT}/rootCA-key.pem" tls.key
|
||||
kubectl create secret generic --from-file=. --dry-run=client -o yaml local-ca > ../local-ca.yaml
|
||||
echo 'type: kubernetes.io/tls' >> ../local-ca.yaml
|
||||
|
||||
cd ..
|
||||
|
||||
cat <<EOF > namespace.yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cert-manager
|
||||
name: cert-manager
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
EOF
|
||||
kubectl apply --server-side=true -f namespace.yaml
|
||||
kubectl apply -n cert-manager --server-side=true -f local-ca.yaml
|
||||
|
||||
# Save the Secret to easily reset the cluster later.
|
||||
install -m 0644 namespace.yaml "${CAROOT}/namespace.yaml"
|
||||
install -m 0600 local-ca.yaml "${CAROOT}/local-ca.yaml"
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
Take care to run the local-ca script each time you create the workload cluster
|
||||
so that Certificates are issued correctly.
|
||||
|
||||
:::
|
||||
|
||||
## Clean Up {#clean-up}
|
||||
|
||||
If you'd like to clean up the resources you created in this guide, remove them
|
||||
with:
|
||||
|
||||
```bash
|
||||
k3d cluster delete workload
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you have a real cluster, apply and explore the manifests Holos renders
|
||||
in the [Quickstart](/docs/quickstart) guide.
|
||||
765
doc/md/guides/quickstart.mdx
Normal file
@@ -0,0 +1,765 @@
|
||||
---
|
||||
description: Try Holos with this quick start guide.
|
||||
slug: /quickstart
|
||||
sidebar_position: 100
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Quickstart
|
||||
|
||||
Welcome to the Holos Quickstart guide. Holos is an open source tool to manage
|
||||
software development platforms safely, easily, and consistently. We'll use
|
||||
Holos to manage a fictional bank's platform, the Bank of Holos. In doing so
|
||||
we'll take the time to explain the foundational concepts of Holos.
|
||||
|
||||
1. **Platform** - Holos breaks a Platform down into Components owned by teams.
|
||||
2. **Component** - Components are CUE wrappers around unmodified upstream
|
||||
vendor Helm Charts, Kustomize Bases, or plain Kubernetes manifests.
|
||||
3. **CUE** - We write CUE to configure the platform. We'll cover the basics of
|
||||
CUE syntax and why Holos uses CUE.
|
||||
4. **Tree Unification** - CUE files are organized into a unified filesystem
|
||||
tree. We'll cover how unification makes it easier and safer for multiple teams
|
||||
to change the platform.
|
||||
|
||||
The Bank of Holos provides a good example of how Holos is designed to make it
|
||||
easier for multiple teams to deliver services on a platform. These teams are:
|
||||
|
||||
- **Platform**
|
||||
- **Software development**
|
||||
- **Security**
|
||||
- **Quality Assurance**
|
||||
|
||||
Here's a screenshot of the retail banking application we'll build and deploy on
|
||||
our platform. We'll keep each of these teams in mind as we work through the
|
||||
guides. Each of our guides focuses on different aspects of delivering the Bank
|
||||
of Holos.
|
||||
|
||||

|
||||
|
||||
## What you'll need {#requirements}
|
||||
|
||||
This guide is intended to be informative without needing to run the commands.
|
||||
If you'd like to render the platform and apply the manifests to a real Cluster,
|
||||
complete the [Local Cluster Guide](/docs/guides/local-cluster) before this
|
||||
guide.
|
||||
|
||||
You'll need the following tools installed to run the commands in this guide.
|
||||
|
||||
1. [holos](/docs/install) - to build the Platform.
|
||||
2. [helm](https://helm.sh/docs/intro/install/) - to render Holos Components that
|
||||
wrap Helm charts.
|
||||
3. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to render Holos
|
||||
Components that render with Kustomize.
|
||||
|
||||
## Install Holos
|
||||
|
||||
Start by installing the `holos` command line tool with the following command.
|
||||
If you don't have Go, refer to [Installation](/docs/install/) to download the
|
||||
executable.
|
||||
|
||||
<Tabs groupId="go-install">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
go install github.com/holos-run/holos/cmd/holos@latest
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
go: downloading github.com/holos-run/holos v0.95.1
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
Nearly all day-to-day platform management tasks use the `holos` command line
|
||||
tool to render plain Kubernetes manifests.
|
||||
:::
|
||||
|
||||
## Fork the Git Repository
|
||||
|
||||
Building a software development platform from scratch takes time so we've
|
||||
published an example for our guides. [Fork the Bank of
|
||||
Holos](https://github.com/holos-run/bank-of-holos/fork) to get started.
|
||||
|
||||
Clone the repository to your local machine.
|
||||
|
||||
<Tabs groupId="git-clone">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
# Change YourName
|
||||
git clone https://github.com/YourName/bank-of-holos
|
||||
cd bank-of-holos
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
Cloning into 'bank-of-holos'...
|
||||
remote: Enumerating objects: 1177, done.
|
||||
remote: Counting objects: 100% (1177/1177), done.
|
||||
remote: Compressing objects: 100% (558/558), done.
|
||||
remote: Total 1177 (delta 394), reused 1084 (delta 303), pack-reused 0 (from 0)
|
||||
Receiving objects: 100% (1177/1177), 2.89 MiB | 6.07 MiB/s, done.
|
||||
Resolving deltas: 100% (394/394), done.
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Run the rest of the commands in this guide from the root of the repository.
|
||||
|
||||
## Configure ArgoCD {#configure-argocd}
|
||||
|
||||
The Bank of Holos platform is organized as a collection of software components.
|
||||
Each component represents a piece of software provided by an upstream vendor,
|
||||
for example ArgoCD, or software developed in-house. Components are also used to
|
||||
glue together, or integrate, other components into the platform.
|
||||
|
||||
We'll start by changing the platform to point to our fork. We need to do this
|
||||
so we'll be able to see changes in ArgoCD as we make changes with GitOps.
|
||||
|
||||
<Tabs groupId="argocd-config">
|
||||
<TabItem value="command" label="projects/argocd-config.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
// highlight-next-line
|
||||
RepoURL: "https://github.com/holos-run/bank-of-holos"
|
||||
}
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Change the RepoURL to the URL of your fork. For example:
|
||||
|
||||
<Tabs groupId="F3BF73E3-3A70-40AF-9D4D-7134AF0A1763">
|
||||
<TabItem value="command" label="projects/argocd-config.cue">
|
||||
```diff showLineNumbers
|
||||
diff --git a/projects/argocd-config.cue b/projects/argocd-config.cue
|
||||
index 5264f48..0214e99 100644
|
||||
--- a/projects/argocd-config.cue
|
||||
+++ b/projects/argocd-config.cue
|
||||
@@ -2,5 +2,5 @@ package holos
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
- RepoURL: "https://github.com/holos-run/bank-of-holos"
|
||||
+ RepoURL: "https://github.com/jeffmccune/bank-of-holos"
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
We need to render the platform manifests after we make changes.
|
||||
|
||||
## Render the Platform
|
||||
|
||||
Platform rendering is is the process of looping over all the components in the
|
||||
platform and rendering each one into plain kubernetes manifest files. Holos is
|
||||
designed to write plain manifest files which can be applied to Kubernetes, but
|
||||
stops short of applying them so it's easier for team members to review and
|
||||
understand changes before they're made.
|
||||
|
||||
<Tabs groupId="219C5B3D-1369-45F9-B010-64A87EF71190">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered bank-accounts-db for cluster workload in 142.661334ms
|
||||
rendered bank-ledger-db for cluster workload in 144.041417ms
|
||||
rendered bank-userservice for cluster workload in 157.828709ms
|
||||
rendered bank-ledger-writer for cluster workload in 161.138292ms
|
||||
rendered bank-backend-config for cluster workload in 168.923459ms
|
||||
rendered bank-balance-reader for cluster workload in 171.877875ms
|
||||
rendered bank-secrets for cluster workload in 207.958792ms
|
||||
rendered gateway for cluster workload in 123.572583ms
|
||||
rendered bank-contacts for cluster workload in 144.466291ms
|
||||
rendered bank-transaction-history for cluster workload in 151.520041ms
|
||||
rendered httproutes for cluster workload in 139.590834ms
|
||||
rendered bank-frontend for cluster workload in 309.679834ms
|
||||
rendered app-projects for cluster workload in 107.136083ms
|
||||
rendered ztunnel for cluster workload in 160.679791ms
|
||||
rendered cni for cluster workload in 238.937625ms
|
||||
rendered cert-manager for cluster workload in 178.610834ms
|
||||
rendered istiod for cluster workload in 340.953208ms
|
||||
rendered argocd for cluster workload in 286.277ms
|
||||
rendered local-ca for cluster workload in 98.720208ms
|
||||
rendered external-secrets for cluster workload in 141.459708ms
|
||||
rendered base for cluster workload in 454.356667ms
|
||||
rendered namespaces for cluster workload in 115.401709ms
|
||||
rendered gateway-api for cluster workload in 203.5625ms
|
||||
rendered external-secrets-crds for cluster workload in 525.180209ms
|
||||
rendered crds for cluster workload in 888.406167ms
|
||||
rendered platform in 1.182857542s
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Rendering the platform to plain manifest files allows us to see the changes
|
||||
clearly. We can see this one line change affected dozens ArgoCD Application
|
||||
resources across the platform.
|
||||
|
||||
<Tabs groupId="266D26D4-31FC-45D1-88EF-EAD23BBBDCDD">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
On branch main
|
||||
Your branch is up to date with 'origin/main'.
|
||||
|
||||
Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git restore <file>..." to discard changes in working directory)
|
||||
modified: deploy/clusters/workload/gitops/app-projects.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/argocd-crds.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/argocd.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-accounts-db.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-backend-config.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-balance-reader.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-contacts.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-frontend.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-ledger-db.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-ledger-writer.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-secrets.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-transaction-history.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/bank-userservice.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/cert-manager.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/external-secrets-crds.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/external-secrets.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/gateway-api.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/httproutes.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istio-base.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istio-cni.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istio-gateway.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istio-ztunnel.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/istiod.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/local-ca.application.gen.yaml
|
||||
modified: deploy/clusters/workload/gitops/namespaces.application.gen.yaml
|
||||
modified: projects/argocd-config.cue
|
||||
|
||||
no changes added to commit (use "git add" and/or "git commit -a")
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Take a look at the Application resource for the bank-frontend component to see
|
||||
the changed `spec.source.repoURL` field.
|
||||
|
||||
<Tabs groupId="665E5402-FB42-4975-B654-3922EE73EE07">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git diff deploy/clusters/workload/gitops/bank-frontend.application.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```diff showLineNumbers
|
||||
diff --git a/deploy/clusters/workload/gitops/bank-frontend.application.gen.yaml b/deploy/clusters/workload/gitops/bank-frontend.application.gen.yaml
|
||||
index d8ede55..aed4338 100644
|
||||
--- a/deploy/clusters/workload/gitops/bank-frontend.application.gen.yaml
|
||||
+++ b/deploy/clusters/workload/gitops/bank-frontend.application.gen.yaml
|
||||
@@ -9,5 +9,5 @@ spec:
|
||||
project: bank-frontend
|
||||
source:
|
||||
path: ./deploy/clusters/workload/components/bank-frontend
|
||||
- repoURL: https://github.com/holos-run/bank-of-holos
|
||||
+ repoURL: https://github.com/jeffmccune/bank-of-holos
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
We'll add, commit, and push this change to our fork then take a little time to
|
||||
explain what happened when we made the change and rendered the platform.
|
||||
|
||||
<Tabs groupId="BD6A968F-FFDF-486B-8EC0-BA8B39C19303">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m 'quickstart: change argocd repo url to our fork'
|
||||
git push origin
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main f2f8bc2] quickstart: change argocd repo url to our fork
|
||||
26 files changed, 26 insertions(+), 26 deletions(-)
|
||||
Enumerating objects: 41, done.
|
||||
Counting objects: 100% (41/41), done.
|
||||
Delta compression using up to 14 threads
|
||||
Compressing objects: 100% (31/31), done.
|
||||
Writing objects: 100% (33/33), 2.95 KiB | 2.95 MiB/s, done.
|
||||
Total 33 (delta 28), reused 0 (delta 0), pack-reused 0
|
||||
remote: Resolving deltas: 100% (28/28), completed with 4 local objects.
|
||||
To github.com:jeffmccune/bank-of-holos.git
|
||||
c2951ec..f2f8bc2 main -> main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Platform Rendering Explained
|
||||
|
||||
So what happens when we run `holos render platform`? We saw `holos` write plain
|
||||
manifest files, let's dive into how and why we implemented platform rendering
|
||||
like this.
|
||||
|
||||
### Why do we render the platform? {#why-render-the-platform}
|
||||
|
||||
We built Holos to make the process of managing a platform safer, easier, and
|
||||
more consistent. Before Holos we used Helm, Kustomize, and scripts to glue
|
||||
together all of the software that goes into a platform. Then we coaxed the
|
||||
output of each tool into something that works with GitOps. This approach has a
|
||||
number of shortcomings. We wanted to see the manifests before ArgoCD or Flux
|
||||
applied them, so we wrote a lot of difficult to maintain scripts to get the
|
||||
template output into something useful. We tried avoiding the scripts by having
|
||||
ArgoCD handle the Helm charts directly, but we could no longer see the changes
|
||||
clearly during code review.
|
||||
|
||||
The platform rendering process allows us to have it both ways. We avoid the
|
||||
unsafe text templates and glue scripts by using CUE. We're able to review the
|
||||
exact changes that _will be_ applied during code review because holos renders
|
||||
the whole platform to plain manifest files.
|
||||
|
||||
Finally, because we usually make each change by rendering the whole platform,
|
||||
we're able to see and consider how a single-line change, like the one we just
|
||||
made, affects the whole platform. Before we made Holos we were frustrated with
|
||||
how difficult it was to get this zoomed-out, broad perspective of each change we
|
||||
made.
|
||||
|
||||
### How does platform rendering work? {#how-platform-rendering-works}
|
||||
|
||||
Holos is declarative. CUE provides resources that declare what `holos` needs to
|
||||
do. The output of `holos` is always the same for the same inputs, so `holos` is
|
||||
also idempotent.
|
||||
|
||||
When we run `holos render platform`, CUE builds the Platform specification
|
||||
(spec). This is a fancy way of saying a list of software to manage on each
|
||||
cluster in the platform. The CUE files in the `platform` directory provide the
|
||||
platform spec to `holos`.
|
||||
|
||||
Let's open up two of these CUE files to see how this works. Ignore the other
|
||||
files for now, they behave the same as these two.
|
||||
|
||||
<Tabs groupId="6F01F2F7-C101-4212-A844-0E370B836B54">
|
||||
<TabItem value="argocd" label="platform/argocd.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Manage the component on every cluster in the platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
// highlight-next-line
|
||||
#Platform: Components: "\(Cluster.name)/argocd-crds": {
|
||||
path: "projects/platform/components/argocd/crds"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
// highlight-next-line
|
||||
#Platform: Components: "\(Cluster.name)/argocd": {
|
||||
path: "projects/platform/components/argocd/argocd"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="external-secrets" label="platform/external-secrets.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Manage the component on every cluster in the platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
// highlight-next-line
|
||||
#Platform: Components: "\(Cluster.name)/external-secrets-crds": {
|
||||
path: "projects/platform/components/external-secrets-crds"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
// highlight-next-line
|
||||
#Platform: Components: "\(Cluster.name)/external-secrets": {
|
||||
path: "projects/platform/components/external-secrets"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
There's quite a few new concepts to unpack in these two CUE files.
|
||||
|
||||
1. A Fleet is just a collection of clusters that share a similar, but not
|
||||
identical configuration. Most platforms have a management fleet with one
|
||||
cluster to manage the platform, and a workload fleet for clusters that host the
|
||||
services we deploy onto the platform.
|
||||
2. A Cluster is a Kubernetes cluster. Each component is rendered to plain
|
||||
manifests for a cluster.
|
||||
|
||||
:::important
|
||||
On lines 6 and 10 we see a Component being assigned to the Platform. We also
|
||||
start to dive into the syntax of CUE, which we need to understand a little
|
||||
before going further.
|
||||
:::
|
||||
|
||||
> In its simplest form, CUE looks a lot like JSON. This is because CUE is a
|
||||
superset of JSON. Or, put differently: all valid JSON is CUE.
|
||||
>
|
||||
> 1. C-style comments are allowed
|
||||
> 2. field names without special characters don't need to be quoted
|
||||
> 3. commas after a field are optional (and are usually omitted)
|
||||
> 4. commas after the final element of a list are allowed
|
||||
> 5. **the outermost curly braces in a CUE file are optional**
|
||||
>
|
||||
> JSON objects are called structs in CUE. JSON arrays are called lists, Object
|
||||
members are called fields, which link their name, or label, to a value.
|
||||
|
||||
There are two important things to know about CUE to understand these two files.
|
||||
First, the curly braces have been omitted which is item 5 on the list above.
|
||||
Second, CUE is all about _unification_. These files could have been written
|
||||
like this:
|
||||
|
||||
<Tabs groupId="59FFCCB6-A584-42ED-AC37-1C2BDCF5A523">
|
||||
<TabItem value="argocd" label="platform/argocd.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Manage the component on every cluster in the platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: {
|
||||
// highlight-next-line
|
||||
// Define #Platform.Components
|
||||
// highlight-next-line
|
||||
Components: {
|
||||
"\(Cluster.name)/argocd-crds": {
|
||||
path: "projects/platform/components/argocd/crds"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
|
||||
// highlight-next-line
|
||||
// Define #Platform.Components again!? Error?
|
||||
// highlight-next-line
|
||||
Components: {
|
||||
"\(Cluster.name)/argocd": {
|
||||
path: "projects/platform/components/argocd/argocd"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="external-secrets" label="platform/external-secrets.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Manage the component on every cluster in the platform
|
||||
for Fleet in #Fleets {
|
||||
for Cluster in Fleet.clusters {
|
||||
#Platform: {
|
||||
// highlight-next-line
|
||||
// Define #Platform.Components
|
||||
// highlight-next-line
|
||||
Components: {
|
||||
"\(Cluster.name)/external-secrets-crds": {
|
||||
path: "projects/platform/components/external-secrets-crds"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
|
||||
// highlight-next-line
|
||||
// Define #Platform.Components again!? Error?
|
||||
// highlight-next-line
|
||||
Components: {
|
||||
"\(Cluster.name)/external-secrets": {
|
||||
path: "projects/platform/components/external-secrets"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::important
|
||||
Unlike most other languages, it is common to declare the same field in multiple
|
||||
places. CUE **unifies** the value of the field. We can think of CUE as a
|
||||
Configuration Unification Engine.
|
||||
:::
|
||||
|
||||
Now that we know curly braces can be omitted and values are unified, we can
|
||||
understand how the rest of the CUE files in the platform directory behave.
|
||||
|
||||
:::tip
|
||||
Each CUE file in the platform directory adds components to the
|
||||
`#Platform.Components` struct.
|
||||
:::
|
||||
|
||||
The final file in the directory is responsible for producing the Platform spec.
|
||||
It looks like this.
|
||||
|
||||
<Tabs groupId="166F0925-9405-4571-A0AB-C7E2107876FD">
|
||||
<TabItem value="command" label="platform/platform.gen.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
#Platform.Output
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This file provides the value of the `#Platform.Output` field, the platform spec,
|
||||
to `holos`.
|
||||
|
||||
Let's take a look at that Output value:
|
||||
|
||||
<Tabs groupId="475C92AC-C6DA-4FB9-859C-722921277CFC">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
cue export --out yaml ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```yaml showLineNumbers
|
||||
kind: Platform
|
||||
apiVersion: v1alpha3
|
||||
metadata:
|
||||
name: guide
|
||||
spec:
|
||||
model: {}
|
||||
components: # This is a trimmed list for readability.
|
||||
- path: projects/bank-of-holos/security/components/bank-secrets
|
||||
cluster: workload
|
||||
- path: projects/bank-of-holos/frontend/components/bank-frontend
|
||||
cluster: workload
|
||||
- path: projects/platform/components/argocd/crds
|
||||
cluster: workload
|
||||
- path: projects/platform/components/argocd/argocd
|
||||
cluster: workload
|
||||
- path: projects/platform/components/external-secrets-crds
|
||||
cluster: workload
|
||||
- path: projects/platform/components/external-secrets
|
||||
cluster: workload
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
You don't normally need to execute `cue`, CUE is built into `holos`. We use it
|
||||
here to gain insight.
|
||||
:::
|
||||
|
||||
We see the platform spec is essentially a list of components, each assigned to a
|
||||
cluster.
|
||||
|
||||
:::important
|
||||
Notice CUE unifies `Components` from multiple files into one list.
|
||||
|
||||
We'll see this unification behavior again and again. Unification is the
|
||||
defining characteristic of CUE that makes it a unique, powerful, and _safe_
|
||||
configuration language.
|
||||
:::
|
||||
|
||||
Holos takes this list of components and builds each one by executing:
|
||||
|
||||
```bash
|
||||
holos render component --cluster-name="example" "path/to/the/component"
|
||||
```
|
||||
|
||||
We can think of platform rendering as rendering a list of components, passing
|
||||
the cluster name each time. Rendering each component writes the fully rendered
|
||||
manifest for that component to the `deploy/` directory, organized by cluster for
|
||||
GitOps.
|
||||
|
||||
## Render a Component
|
||||
|
||||
Rendering a component works much the same way as rendering a platform. `holos`
|
||||
uses CUE to produce a specification, then processes it. The specification of a
|
||||
component is called a BuildPlan. A BuildPlan is a list of zero or more
|
||||
kubernetes resources, Helm charts, Kustomize bases, and additional files to
|
||||
write into the `deploy/` directory.
|
||||
|
||||
Let's take a look at the cert-manager component. Notice the
|
||||
`platform/cert-manager.cue` file has the field `path:
|
||||
"projects/platform/components/cert-manager"`. This path indicates where to
|
||||
start working with the cert-manager component.
|
||||
|
||||
<Tabs groupId="129DD743-0FE3-44C0-ACA4-6569C98BA40E">
|
||||
<TabItem value="cert-manager" label="projects/platform/components/cert-manager/cert-manager.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
// highlight-next-line
|
||||
(#Helm & Chart).BuildPlan
|
||||
|
||||
// highlight-next-line
|
||||
let Chart = {
|
||||
Name: "cert-manager"
|
||||
// #CertManager is defined in projects/cert-manager.cue
|
||||
// highlight-next-line
|
||||
Version: #CertManager.Version
|
||||
// highlight-next-line
|
||||
Namespace: #CertManager.Namespace
|
||||
|
||||
Repo: name: "jetstack"
|
||||
Repo: url: "https://charts.jetstack.io"
|
||||
|
||||
// CUE offers type checking and validation of Helm values.
|
||||
// highlight-next-line
|
||||
Values: installCRDs: true
|
||||
// highlight-next-line
|
||||
Values: startupapicheck: enabled: false
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="root" label="projects/cert-manager.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Platform wide configuration
|
||||
#CertManager: {
|
||||
// highlight-next-line
|
||||
Version: "1.15.3"
|
||||
// highlight-next-line
|
||||
Namespace: "cert-manager"
|
||||
}
|
||||
|
||||
// Register the namespace
|
||||
// The underscore indicates the value is defined elsewhere in CUE.
|
||||
#Namespaces: (#CertManager.Namespace): _
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This file introduces a few new concepts.
|
||||
|
||||
1. Line 4 indicates this component produces a BuildPlan that wraps a Helm Chart.
|
||||
2. On line 6 `let` binds a name to an expression for the current scope. The
|
||||
current file in this case.
|
||||
3. Notice Chart is referenced on line 4 before it's bound on line 6. **Order is
|
||||
irrelevant in CUE**. Complex changes are simpler and easier when we don't have
|
||||
to think about order.
|
||||
4. The chart version and namespace are defined in a different file closer to the
|
||||
root, `projects/cert-manager.cue`
|
||||
5. We define Helm values in CUE to take advantage of strong type checking and
|
||||
manage multiple Helm charts consistently with platform wide values.
|
||||
|
||||
Let's take a look at the BuildPlan this CUE configuration defines.
|
||||
|
||||
<Tabs groupId="B54D5791-4E5B-4148-A368-62D9BE80760C">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
cue export --out yaml ./projects/platform/components/cert-manager
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```yaml showLineNumbers
|
||||
kind: BuildPlan
|
||||
apiVersion: v1alpha3
|
||||
spec:
|
||||
components:
|
||||
resources:
|
||||
gitops/cert-manager:
|
||||
kind: KubernetesObjects
|
||||
apiVersion: v1alpha3
|
||||
metadata:
|
||||
name: gitops/cert-manager
|
||||
namespace: cert-manager
|
||||
deployFiles:
|
||||
clusters/no-name/gitops/cert-manager.application.gen.yaml: |
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: cert-manager
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: platform
|
||||
source:
|
||||
path: ./deploy/clusters/no-name/components/cert-manager
|
||||
repoURL: https://github.com/jeffmccune/bank-of-holos
|
||||
targetRevision: main
|
||||
skip: false
|
||||
helmChartList:
|
||||
- kind: HelmChart
|
||||
apiVersion: v1alpha3
|
||||
chart:
|
||||
name: cert-manager
|
||||
version: 1.15.3
|
||||
release: cert-manager
|
||||
repository:
|
||||
name: jetstack
|
||||
url: https://charts.jetstack.io
|
||||
valuesContent: |
|
||||
installCRDs: true
|
||||
startupapicheck:
|
||||
enabled: false
|
||||
enableHooks: false
|
||||
metadata:
|
||||
name: cert-manager
|
||||
namespace: cert-manager
|
||||
apiObjectMap: {}
|
||||
skip: false
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::important
|
||||
Again, you don't normally need to execute `cue`, it's built into `holos`. We
|
||||
use it here to show how Holos works with Helm.
|
||||
:::
|
||||
|
||||
Looking at the BuildPlan, we see `holos` will render the Helm chart into the
|
||||
deploy directory along with an ArgoCD Application resource in the `gitops/`
|
||||
directory.
|
||||
|
||||
:::tip
|
||||
The BuildPlan API is flexible enough to write any file into the `deploy/`
|
||||
directory. Holos uses this flexibility to support both Flux and ArgoCD.
|
||||
:::
|
||||
|
||||
When we run `cue export`, we get back a Core API BuildPlan. The BuildPlan is
|
||||
produced by the `#Helm` definition on line 4 which is part of the Author API.
|
||||
The Core API is the contract between CUE and `holos`. As such, it's not as
|
||||
friendly as the Author API. The Author API is the contract component authors
|
||||
and platform engineers use to configure and manage the platform. The Author API
|
||||
is meant for people, the Core API is meant for machines. This explains why we
|
||||
see quite a few fields in the exported BuildPlan we didn't cover in this guide.
|
||||
Day to day we don't need to be concerned with those fields because the Author
|
||||
API handles them for us.
|
||||
|
||||
:::tip
|
||||
Our intent is to provide an ergonomic way to manage the platform with the Author
|
||||
API.
|
||||
:::
|
||||
|
||||
When the Author API doesn't offer a path forward, authors may use the Core API
|
||||
directly from CUE. We can think of the Core API as an escape hatch for the
|
||||
Author API. We'll see some examples of this in action in the more advanced
|
||||
guides.
|
||||
|
||||
## Next Steps
|
||||
|
||||
Thank you for finishing the Quickstart guide. Dive deeper with the next guide
|
||||
on how to [Deploy a Service] which explains how to take one of your existing
|
||||
Helm charts or Deployments and manage it with Holos.
|
||||
|
||||
[application]: https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/
|
||||
[schema]: /docs/api/schema/v1alpha3/
|
||||
[core]: /docs/api/core/v1alpha3/
|
||||
[Deploy a Service]: /docs/guides/deploy-a-service/
|
||||
[Manage a Project]: /docs/guides/manage-a-project/
|
||||
20
doc/md/introduction.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
description: Holos Documentation
|
||||
slug: /
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
Welcome to Holos. Holos is an open source tool to manage software development
|
||||
platforms safely, easily, and consistently.
|
||||
|
||||
Our documentation is organized into [Guides] and the [API Reference].
|
||||
|
||||
:::tip
|
||||
Please start with the [Quickstart] guide to learn who Holos is for, what
|
||||
problems it solves, and if it can solve problems you have.
|
||||
:::
|
||||
|
||||
[Guides]: /docs/guides/
|
||||
[API Reference]: /docs/api/
|
||||
[Quickstart]: /docs/quickstart/
|
||||
@@ -1,311 +0,0 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Quickstart Guide
|
||||
|
||||
This guide shows you the basics of how Holos. You'll deploy a Helm chart to
|
||||
Kubernetes using a Component to see how Holos makes the process safer, easier,
|
||||
and more consistent.
|
||||
|
||||
## 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 Holos components that wrap upstream Helm charts.
|
||||
3. [k3d](https://k3d.io/#installation) - to provide a Kubernetes API server.
|
||||
4. [OrbStack](https://docs.orbstack.dev/install) or [Docker](https://docs.docker.com/get-docker/) - to use k3d.
|
||||
5. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to interact with the k8s api server.
|
||||
|
||||
## Install Holos
|
||||
|
||||
Install Holos with the following command or other methods listed on the
|
||||
[Installation](/docs/install/) page.
|
||||
|
||||
```bash
|
||||
go install github.com/holos-run/holos/cmd/holos@latest
|
||||
```
|
||||
|
||||
## Git repository
|
||||
|
||||
Start by initializing an empty Git repository. Holos is designed to operate
|
||||
against local files in a Git repository.
|
||||
|
||||
<Tabs groupId="init">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
mkdir holos-quickstart
|
||||
cd holos-quickstart
|
||||
git init
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
Initialized empty Git repository in /holos-quickstart/.git/
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This guide assumes commands are run from the root directory of this Git
|
||||
repository unless otherwise stated.
|
||||
|
||||
## Generate the Platform {#Generate-Platform}
|
||||
|
||||
Generate the Platform code in the repository root. A Platform refers to all of
|
||||
the software and services integrated together to provide your organization's
|
||||
software development platform. In this guide the platform will contain a single
|
||||
Component to demonstrate how the concepts fit together.
|
||||
|
||||
```bash
|
||||
holos generate platform quickstart
|
||||
```
|
||||
|
||||
Commit the generated platform config to the repository.
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos generate platform quickstart - $(holos --version)"
|
||||
```
|
||||
|
||||
## Create a Component
|
||||
|
||||
The platform you generated is empty. Rendering the platform succeeds, but does
|
||||
nothing because there are no Components listed in the Platform spec:
|
||||
|
||||
```cue
|
||||
package holos
|
||||
|
||||
import core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
|
||||
core.#Platform & {
|
||||
metadata: name: "quickstart"
|
||||
}
|
||||
```
|
||||
|
||||
<Tabs groupId="render">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```bash
|
||||
# No output is produced, the Platform contains no Components.
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Generate the CUE code definition for a Component that wraps the podinfo Helm
|
||||
chart.
|
||||
|
||||
<Tabs groupId="gen-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
mkdir -p components
|
||||
(cd components && holos generate component helm podinfo)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The HelmChart Component is defined in the `components/podinfo/podinfo.cue` file, for example:
|
||||
|
||||
```cue
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "podinfo"
|
||||
Version: "6.6.2"
|
||||
Namespace: "default"
|
||||
|
||||
Repo: name: "podinfo"
|
||||
Repo: url: "https://stefanprodan.github.io/podinfo"
|
||||
|
||||
Values: {}
|
||||
}
|
||||
```
|
||||
|
||||
In this example we're providing the minimal information about the Helm chart we
|
||||
want to manage in this Component. The name, version, Kubernetes namespace to
|
||||
deploy into, and the chart repository location.
|
||||
|
||||
This chart deploys cleanly with no values provided, but we include an empty
|
||||
struct to illustrate how Holos improves the consistency and safety of Helm
|
||||
values by taking advantage the strong type checking in CUE. Shared values, such
|
||||
as the organization domain name, can safely be passed to all Components across
|
||||
all clusters in the Platform.
|
||||
|
||||
## Render the Component
|
||||
|
||||
Individual components can be rendered without needing to be included in a
|
||||
Platform spec, useful when developing a new component.
|
||||
|
||||
<Tabs groupId="render-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render component ./components/podinfo --cluster-name=default
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
cached
|
||||
rendered podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
First, the command caches the helm chart locally to speed up subsequent
|
||||
renderings. Then the command executes helm to produce the output which is
|
||||
written into the deploy directory.
|
||||
|
||||
<Tabs groupId="tree-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
└── default
|
||||
└── components
|
||||
└── podinfo
|
||||
└── podinfo.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The component is deployed to one cluster named default. The same component is
|
||||
often deployed to multiple clusters, for example east and west for reliability.
|
||||
|
||||
This example is equivalent to executing `helm template` on the chart.
|
||||
|
||||
## Mix in an ArgoCD Application
|
||||
|
||||
So far we've seen how Holos is a convenient wrapper around Helm, but we haven't
|
||||
yet seen how it makes it easier to consistently and safely manage all of the
|
||||
software that goes into a platform. We'll mix in an ArgoCD
|
||||
[Application][application] resource to manage the podinfo Component with GitOps.
|
||||
We'll define this configuration in a way that is automatically and consistently
|
||||
re-used across all Components added to the Platform in the future, including
|
||||
Components which are not Helm charts.
|
||||
|
||||
Create a new file named `argocd.cue` in the root of your git repository with the
|
||||
following contents:
|
||||
|
||||
<Tabs groupId="argocd-config">
|
||||
<TabItem value="command" label="File: argocd.cue">
|
||||
```cue
|
||||
package holos
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
RepoURL: "https://example.com/holos-quickstart.git"
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="note" label="Note">
|
||||
If you plan to apply the rendered output to a real cluster, change the RepoURL
|
||||
to the url of the git repository you created in this guide. It is sufficient to
|
||||
keep the example URL if you're getting a feel for Holos and inspecting the
|
||||
rendered output without applying it to a live cluster.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
With this file in place, render the component again.
|
||||
|
||||
<Tabs groupId="render-podinfo-argocd">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render component ./components/podinfo --cluster-name=default
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
wrote deploy file
|
||||
rendered gitops/podinfo
|
||||
rendered podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The render command uses the cached chart this time around. Then, the helm
|
||||
template output is rendered along with an additional ArgoCD Application resource
|
||||
for GitOps in the `podinfo.application.gen.yaml` file.
|
||||
|
||||
<Tabs groupId="tree-podinfo-argocd">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
└── default
|
||||
├── components
|
||||
│ └── podinfo
|
||||
│ └── podinfo.gen.yaml
|
||||
└── gitops
|
||||
└── podinfo.application.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The Application resource looks like:
|
||||
|
||||
<Tabs groupId="podinfo-application">
|
||||
<TabItem value="file" label="podinfo.application.gen.yaml">
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
path: ./deploy/clusters/default/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
|
||||
Holos will generate a similar Application resource for all additional Components
|
||||
added to your Platform.
|
||||
|
||||
:::
|
||||
|
||||
In this section we learned how Holos provides a simple way to add an ArgoCD
|
||||
Application resource for the podinfo Component. Holos further provides
|
||||
consistency by creating a similar Application resource for every subsequent
|
||||
Component added to the platform in the future, all by defining the configuration
|
||||
of ArgoCD in a single place.
|
||||
|
||||
[application]: https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/
|
||||
|
||||
|
||||
## Quickstart Recap {#quickstart-recap}
|
||||
|
||||
In this guide we learned how to:
|
||||
|
||||
1. Install Holos.
|
||||
2. Generate a Git repository for the Platform config.
|
||||
3. Create a Component that wraps the upstream podinfo Helm Chart without modifications.
|
||||
4. Render individual components.
|
||||
5. Mix in an ArgoCD Application resource to every Component in the Platform.
|
||||
13
doc/md/start.md
Normal file
@@ -0,0 +1,13 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Get Started
|
||||
|
||||
## Start with the [Quickstart] guide
|
||||
|
||||
---
|
||||
|
||||
These documents provide additional context to supplement the [Quickstart] guide.
|
||||
|
||||
<DocCardList />
|
||||
|
||||
[Quickstart]: /docs/quickstart/
|
||||
15
doc/md/start/comparison.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
description: Compare Holos with other tools in the ecosystem.
|
||||
slug: /comparison
|
||||
sidebar_position: 300
|
||||
---
|
||||
|
||||
# Comparison
|
||||
|
||||
## Helm
|
||||
|
||||
## Kustomize
|
||||
|
||||
## ArgoCD
|
||||
|
||||
## Flux
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
description: Learn the concepts and domain language Holos uses.
|
||||
slug: /concepts
|
||||
sidebar_position: 200
|
||||
---
|
||||
|
||||
# Concepts
|
||||
|
||||
## Introduction
|
||||
@@ -23,21 +29,34 @@ platform engineers.
|
||||
- [Platform](<#platform>) - A collection of Components integrated into a software development platform.
|
||||
- [Model](<#model>) - Structured data included in the Platform specification, available to all Components. For example, your organization's domain name.
|
||||
- [Rendering](<#rendering>) - Holos is a tool that makes the process of rendering Kubernetes manifests safer, easier, and consistent.
|
||||
- [Cluster](<#cluster>) - A Kubernetes cluster. Components are rendered for and applied to a Cluster.
|
||||
- [Fleet](<#fleet>) - A collection of Clusters with a similar purpose. A Platform is typically composed of two Fleets, one for management the second for workloads.
|
||||
|
||||
```mermaid
|
||||
graph BT
|
||||
graph TB
|
||||
Platform[<a href="#platform">Platform</a>]
|
||||
Component[<a href="#component">Components</a>]
|
||||
Cluster[<a href="#cluster">Cluster</a>]
|
||||
Fleet[<a href="#fleet">Fleet</a>]
|
||||
Component[<a href="#component">Component</a>]
|
||||
Helm[<a href="#component">Helm</a>]
|
||||
Kustomize[<a href="#component">Kustomize</a>]
|
||||
CUE[<a href="#component">CUE</a>]
|
||||
|
||||
Component --> Platform
|
||||
Cluster --> Platform
|
||||
Fleet --> Cluster
|
||||
Component --> Fleet
|
||||
Helm --> Component
|
||||
Kustomize --> Component
|
||||
CUE --> Component
|
||||
```
|
||||
|
||||
:::tip
|
||||
This graph is organized as a tree. We often say configuration at the root
|
||||
defines the broad Platform. Configuration at a leaf defines a Component of the
|
||||
Platform. The concept of a tree also reflects the filesystem organization of
|
||||
the configuration.
|
||||
:::
|
||||
|
||||
<!--
|
||||
|
||||
```mermaid
|
||||
@@ -336,6 +355,16 @@ graph LR
|
||||
FS --> kubectl --> C
|
||||
```
|
||||
|
||||
## Cluster
|
||||
|
||||
A Cluster represents a Kubernetes cluster. One component may be reused across
|
||||
multiple different Clusters.
|
||||
|
||||
## Fleet
|
||||
|
||||
A Fleet represents a group of Clusters that share a similar purpose. A Platform
|
||||
typically has two Fleets, one for management and one for workloads.
|
||||
|
||||
[krm]: https://docs.google.com/document/d/1RmHXdLhNbyOWPW_AtnnowaRfGejw-qlKQIuLKQWlwzs/view#heading=h.sa6p0aye4ide
|
||||
[Platform]: /docs/api/core/v1alpha2/#Platform
|
||||
[BuildPlan]: /docs/api/core/v1alpha2/#BuildPlan
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
description: Install the Holos executable.
|
||||
slug: /install
|
||||
sidebar_position: 100
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
Holos is distributed as a single file executable.
|
||||
@@ -4,7 +4,7 @@ import type * as Preset from '@docusaurus/preset-classic';
|
||||
|
||||
const config: Config = {
|
||||
title: 'Holos',
|
||||
tagline: 'The Holistic Package Manager for Cloud Native Applications',
|
||||
tagline: 'The Holistic Platform Manager',
|
||||
favicon: 'img/favicon.ico',
|
||||
|
||||
// Set the production url of your site here
|
||||
@@ -41,12 +41,7 @@ const config: Config = {
|
||||
[
|
||||
'@docusaurus/plugin-client-redirects',
|
||||
{
|
||||
redirects: [
|
||||
{
|
||||
from: "/docs/tutorial/local/k3d/",
|
||||
to: "/docs/guides/try-holos/",
|
||||
},
|
||||
],
|
||||
redirects: [],
|
||||
},
|
||||
],
|
||||
],
|
||||
@@ -98,19 +93,14 @@ const config: Config = {
|
||||
items: [
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'quickstart/index',
|
||||
docId: 'guides/quickstart',
|
||||
position: 'left',
|
||||
label: 'Try Holos',
|
||||
},
|
||||
{ to: '/docs', label: 'Docs', position: 'left' },
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'concepts',
|
||||
position: 'left',
|
||||
label: 'Docs',
|
||||
},
|
||||
{
|
||||
type: 'docSidebar',
|
||||
sidebarId: 'api',
|
||||
docId: 'api',
|
||||
position: 'left',
|
||||
label: 'API',
|
||||
},
|
||||
@@ -135,7 +125,7 @@ const config: Config = {
|
||||
title: 'Docs',
|
||||
items: [
|
||||
{
|
||||
label: 'Get Started',
|
||||
label: 'Quickstart',
|
||||
to: '/docs/quickstart',
|
||||
},
|
||||
{
|
||||
@@ -144,11 +134,11 @@ const config: Config = {
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
to: '/docs/intro',
|
||||
to: '/docs',
|
||||
},
|
||||
{
|
||||
label: 'API Reference',
|
||||
to: '/docs/api/core/v1alpha2',
|
||||
to: '/docs/api',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -12,30 +12,63 @@ import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
||||
*/
|
||||
const sidebars: SidebarsConfig = {
|
||||
doc: [
|
||||
'quickstart/index',
|
||||
'concepts',
|
||||
'install',
|
||||
'comparison',
|
||||
],
|
||||
api: [
|
||||
'introduction',
|
||||
{
|
||||
label: 'Schema',
|
||||
type: 'category',
|
||||
collapsed: false,
|
||||
items: [
|
||||
'api/schema/v1alpha3',
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Core API',
|
||||
label: 'Getting Started',
|
||||
type: 'category',
|
||||
collapsed: true,
|
||||
link: { type: 'doc', id: 'start' },
|
||||
items: [
|
||||
'api/core/v1alpha3',
|
||||
'api/core/v1alpha2',
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'start',
|
||||
},
|
||||
],
|
||||
},
|
||||
'cli',
|
||||
{
|
||||
label: 'Guides',
|
||||
type: 'category',
|
||||
collapsed: false,
|
||||
link: { type: 'doc', id: 'guides' },
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'guides',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'API Reference',
|
||||
type: 'category',
|
||||
collapsed: true,
|
||||
link: { type: 'doc', id: 'api' },
|
||||
items: [
|
||||
{
|
||||
label: 'Author API',
|
||||
type: 'category',
|
||||
link: { type: 'doc', id: 'api/author' },
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'api/author',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Core API',
|
||||
type: 'category',
|
||||
link: { type: 'doc', id: 'api/core' },
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'api/core',
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ const FeatureList: FeatureItem[] = [
|
||||
description: (
|
||||
<>
|
||||
Reduce risk and increase confidence in your configuration changes.
|
||||
Holos offers clear visibility into complete resource configuration
|
||||
<i>before</i> being applied.
|
||||
Holos offers clear visibility into platform wide changes before the
|
||||
change is made.
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
/* Enable wrapping by default for mobile */
|
||||
/* pre code {
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
} */
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-link-color: #268bd2;
|
||||
|
||||
@@ -18,22 +18,17 @@ function HomepageHeader() {
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
<p className="projectDesc">
|
||||
Holos adds CUE's type safety, unified structure, and strong validation
|
||||
features to your current software packages, including Helm and
|
||||
Kustomize. These features make the experience of integrating software
|
||||
packages into a holistic platform a pleasant journey.
|
||||
features to your Kubernetes configuration manifests, including Helm
|
||||
and Kustomize. These features make the experience of integrating
|
||||
software into a holistic platform a pleasant journey.
|
||||
</p>
|
||||
<div className={styles.buttons}>
|
||||
<Link
|
||||
className="button button--secondary button--lg"
|
||||
to="docs/quickstart">
|
||||
Get Started
|
||||
</Link>
|
||||
<span className={styles.divider}></span>
|
||||
<Link
|
||||
className="button button--primary button--lg"
|
||||
to="docs/concepts">
|
||||
Learn More
|
||||
</Link>
|
||||
<span className={styles.divider}></span>
|
||||
</div>
|
||||
</div>
|
||||
</header >
|
||||
@@ -44,8 +39,8 @@ export default function Home(): JSX.Element {
|
||||
const { siteConfig } = useDocusaurusContext();
|
||||
return (
|
||||
<Layout
|
||||
title={`${siteConfig.title} Package Manager`}
|
||||
description="Holos adds CUE's type safety, unified structure, and strong validation features to your current software packages, including Helm and Kustomize.">
|
||||
title={`${siteConfig.title} Platform Manager`}
|
||||
description="Holos adds CUE's type safety, unified structure, and strong validation features to your Kubernetes configuration manifests, including Helm and Kustomize.">
|
||||
<HomepageHeader />
|
||||
<main>
|
||||
<HomepageFeatures />
|
||||
|
||||
|
Before Width: | Height: | Size: 461 KiB After Width: | Height: | Size: 480 KiB |
BIN
doc/website/static/img/social-card-blank.png
Normal file
|
After Width: | Height: | Size: 477 KiB |
38
doc/website/static/scripts/local-ca
Executable file
@@ -0,0 +1,38 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
mkcert --install
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
# Create the local CA Secret with ca.crt, tls.crt, tls.key
|
||||
|
||||
mkdir local-ca
|
||||
cd local-ca
|
||||
CAROOT="$(mkcert -CAROOT)"
|
||||
cp -p "${CAROOT}/rootCA.pem" ca.crt
|
||||
cp -p "${CAROOT}/rootCA.pem" tls.crt
|
||||
cp -p "${CAROOT}/rootCA-key.pem" tls.key
|
||||
kubectl create secret generic --from-file=. --dry-run=client -o yaml local-ca > ../local-ca.yaml
|
||||
cd ..
|
||||
|
||||
echo 'type: kubernetes.io/tls' >> local-ca.yaml
|
||||
kubectl apply --server-side=true -f- <<EOF
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cert-manager
|
||||
name: cert-manager
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
EOF
|
||||
kubectl apply -n cert-manager --server-side=true -f local-ca.yaml
|
||||
38
doc/website/static/scripts/local-dns
Normal file
@@ -0,0 +1,38 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
brew install dnsmasq
|
||||
|
||||
cat <<EOF >"$(brew --prefix)/etc/dnsmasq.d/holos.localhost.conf"
|
||||
# Refer to https://holos.run/docs/tutorial/local/k3d/
|
||||
address=/holos.localhost/127.0.0.1
|
||||
EOF
|
||||
|
||||
if [[ -r /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist ]]; then
|
||||
echo "dnsmasq already configured"
|
||||
else
|
||||
sudo cp "$(brew list dnsmasq | grep 'dnsmasq.plist$')" \
|
||||
/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl unload /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
dscacheutil -flushcache
|
||||
echo "dnsmasq configured"
|
||||
fi
|
||||
|
||||
sudo mkdir -p /etc/resolver
|
||||
sudo tee /etc/resolver/holos.localhost <<EOF
|
||||
domain holos.localhost
|
||||
nameserver 127.0.0.1
|
||||
EOF
|
||||
sudo killall -HUP mDNSResponder
|
||||
|
||||
echo "all done."
|
||||
@@ -52,33 +52,13 @@ func NewComponent() *cobra.Command {
|
||||
cmd := command.New("component")
|
||||
cmd.Short = "generate a component from an embedded schematic"
|
||||
|
||||
cmd.AddCommand(NewCueComponent())
|
||||
cmd.AddCommand(NewHelmComponent())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewHelmComponent() *cobra.Command {
|
||||
cmd := command.New("helm")
|
||||
cmd.Short = "generate a helm component from a schematic"
|
||||
|
||||
for _, name := range generate.HelmComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("helm", name))
|
||||
for _, name := range generate.Components("v1alpha3") {
|
||||
cmd.AddCommand(makeSchematicCommand("v1alpha3", name))
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCueComponent() *cobra.Command {
|
||||
cmd := command.New("cue")
|
||||
cmd.Short = "generate a cue component from a schematic"
|
||||
|
||||
for _, name := range generate.CueComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("cue", name))
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func makeSchematicCommand(kind, name string) *cobra.Command {
|
||||
cmd := command.New(name)
|
||||
cfg, err := generate.NewSchematic(filepath.Join("components", kind), name)
|
||||
|
||||
@@ -81,22 +81,10 @@ func (s *Schematic) FlagSet() *flag.FlagSet {
|
||||
return fs
|
||||
}
|
||||
|
||||
// CueComponents returns a slice of embedded component schematics or nil if there are none.
|
||||
func CueComponents() []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "cue"))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dirs := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
dirs = append(dirs, entry.Name())
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// HelmComponents returns a slice of embedded component schematics or nil if there are none.
|
||||
func HelmComponents() []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "helm"))
|
||||
// Components returns a slice of embedded component schematics or nil if there
|
||||
// are none.
|
||||
func Components(name string) []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, name))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@@ -131,8 +119,8 @@ func makeRenderFunc[T any](log *slog.Logger, path string, cfg T) func([]byte) *b
|
||||
func GenerateComponent(ctx context.Context, kind string, name string, cfg *Schematic) error {
|
||||
// use name from args to build the source path
|
||||
path := filepath.Join(componentsRoot, kind, name)
|
||||
// use cfg.Name from flags to build the destination path
|
||||
dstPath := filepath.Join(getCwd(ctx), cfg.Name)
|
||||
// write to the current directory.
|
||||
dstPath := filepath.Join(getCwd(ctx))
|
||||
log := logger.FromContext(ctx).With("name", cfg.Name, "path", dstPath)
|
||||
log.DebugContext(ctx, "mkdir")
|
||||
if err := os.MkdirAll(dstPath, os.ModePerm); err != nil {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||