8.1 KiB
Simple addition of one string value
Suppose you have several distinct cloud projects (on GCP or AWS or whatever) named:
- cat-111
- dog-222
- fox-333
These might be project names within the company, cloud billing identifiers, or both.
Further suppose
-
You want to deploy these projects to different k8s namespaces, named after the projects.
-
You need to specify the project name in various resource subfields.
-
You want to name the configuration directories using the project name.
Additionally you might want to deploy the projects one at a time, or all at once.
Ideally, you'll want to avoid specifying the project name in more than one place (i.e. you want to stay DRY).
Here's a possible layout:
├── all │ └── kustomization.yaml │ ├── bases │ └── iam-iap-tunnel │ ├── kustomization.yaml │ └── policymembers.yaml │ └── projects ├── cat-111 │ └── kustomization.yaml ├── dog-222 │ └── kustomization.yaml └── fox-333 └── kustomization.yaml
This layout allows each project to be individually buildable:
kustomize build projects/cat-111 kustomize build projects/dog-222 kustomize build projects/fox-333
or collectively buildable:
kustomize build all
Make a place to work:
DEMO_HOME=$(mktemp -d)
mkdir -p $DEMO_HOME/bases/iam-iap-tunnel
mkdir -p $DEMO_HOME/projects/cat-111
mkdir -p $DEMO_HOME/projects/dog-222
mkdir -p $DEMO_HOME/projects/fox-333
To ground this example with a common problem, assume a set of engineers:
who need particular access to one or more projects.
Define an instance of IAMCustomRole:
cat <<'EOF' >$DEMO_HOME/bases/iam-iap-tunnel/customroles.yaml
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMCustomRole
metadata:
name: engineer
spec:
title: Colorful Engineer
permissions:
- iap.tunnelInstances.accessViaIAP
stage: GA
EOF
Define corresponding instances of IAMPolicyMember.
The resourceRef/external fields in these instances
are intentionally incomplete, and will be completed
by kustomize below.
The boilerplate in these instances could be removed by making a custom generator, but that's for different tutorial.
cat <<'EOF' >$DEMO_HOME/bases/iam-iap-tunnel/policymembers.yaml
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: iap-tunnel-red
spec:
member: user:red@example.com
role: roles/engineer
resourceRef:
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
kind: Project
external: projects
---
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: iap-tunnel-blue
spec:
member: user:blue@example.com
role: roles/engineer
resourceRef:
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
kind: Project
external: projects
---
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: iap-tunnel-yellow
spec:
member: user:yellow@example.com
role: roles/engineer
resourceRef:
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
kind: Project
external: projects
EOF
Make a base that combines these:
cat <<'EOF' >$DEMO_HOME/bases/iam-iap-tunnel/kustomization.yaml
resources:
- customroles.yaml
- policymembers.yaml
EOF
Make a transformer, which at the moment has no equivalent directive in the kustomization file.
It's purpose will be more evident momentarily.
mkdir -p $DEMO_HOME/transformers/setProject
cat <<'EOF' >$DEMO_HOME/transformers/setProject/kustomization.yaml
resources:
- setProject.yaml
EOF
cat <<'EOF' >$DEMO_HOME/transformers/setProject/setProject.yaml
apiVersion: builtin
kind: ValueAddTransformer
metadata:
name: dirNameAdd
# Omitting the 'value:' field means that the current
# kustomization root directory name will be used as
# the value.
# value: not specified!
targets:
- fieldPath: metadata/namespace
- selector:
kind: IAMPolicyMember
fieldPath: spec/resourceRef/external
filePathPosition: 2
EOF
Now make the cat, dog and fox variants.
These are the targets that one could independently apply to a cluster.
cat <<'EOF' >$DEMO_HOME/projects/cat-111/kustomization.yaml
resources:
- ../../bases/iam-iap-tunnel
transformers:
- ../../transformers/setProject
EOF
cat <<'EOF' >$DEMO_HOME/projects/dog-222/kustomization.yaml
resources:
- ../../bases/iam-iap-tunnel
transformers:
- ../../transformers/setProject
EOF
cat <<'EOF' >$DEMO_HOME/projects/fox-333/kustomization.yaml
resources:
- ../../bases/iam-iap-tunnel
transformers:
- ../../transformers/setProject
EOF
Then, optionally, a target to deploy all the projects at once:
mkdir -p $DEMO_HOME/all
cat <<'EOF' >$DEMO_HOME/all/kustomization.yaml
resources:
- ../projects/cat-111
- ../projects/dog-222
- ../projects/fox-333
EOF
The layout is now:
tree $DEMO_HOME
It should look like:
/tmp/someTmpDir ├── all │ └── kustomization.yaml ├── bases │ └── iam-iap-tunnel │ ├── customroles.yaml │ ├── kustomization.yaml │ └── policymembers.yaml ├── projects │ ├── cat-111 │ │ └── kustomization.yaml │ ├── dog-222 │ │ └── kustomization.yaml │ └── fox-333 │ └── kustomization.yaml └── transformers └── setProject ├── kustomization.yaml └── setProject.yaml
The expected output from building the dog project is as follows:
cat <<EOF >$DEMO_HOME/out_expected.yaml
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMCustomRole
metadata:
name: engineer
namespace: dog-222
spec:
permissions:
- iap.tunnelInstances.accessViaIAP
stage: GA
title: Colorful Engineer
---
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: iap-tunnel-blue
namespace: dog-222
spec:
member: user:blue@example.com
resourceRef:
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
external: projects/dog-222
kind: Project
role: roles/engineer
---
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: iap-tunnel-red
namespace: dog-222
spec:
member: user:red@example.com
resourceRef:
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
external: projects/dog-222
kind: Project
role: roles/engineer
---
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: iap-tunnel-yellow
namespace: dog-222
spec:
member: user:yellow@example.com
resourceRef:
apiVersion: resourcemanager.cnrm.cloud.google.com/v1beta1
external: projects/dog-222
kind: Project
role: roles/engineer
EOF
In this output, the namespace of all instances is the
project name, and the project name also appears
in the resourceRef field of the IAMPolicyMember instances.
Confirm this is happens:
kustomize build $DEMO_HOME/projects/dog-222 >$DEMO_HOME/out_actual.yaml
Confirm expectations:
diff $DEMO_HOME/out_actual.yaml $DEMO_HOME/out_expected.yaml
Build all the projects at once like this:
kustomize build $DEMO_HOME/all