apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: workloadidentities.gcp.livewyer.io
creationTimestamp: null
spec:
compositeTypeRef:
apiVersion: gcp.livewyer.io/v1alpha1
kind: WorkloadIdentity
mode: Pipeline
pipeline:
- step: go-templating
functionRef:
name: upbound-function-go-templating
input:
apiVersion: gotemplating.fn.crossplane.io/v1beta1
inline:
template: >
{{- $id := $.observed.composite.resource.metadata.name }}
{{- $ns := default "default"
$.observed.composite.resource.metadata.namespace }}
{{- $annotations := default (dict)
$.observed.composite.resource.metadata.annotations }}
{{- $labels := default (dict)
$.observed.composite.resource.metadata.labels }}
{{- $spec := $.observed.composite.resource.spec }}
---
apiVersion: cloudplatform.gcp.m.upbound.io/v1beta1
kind: ServiceAccount
metadata:
name: {{ $id }}
namespace: {{ $ns }}
annotations:
{{ setResourceNameAnnotation (printf "serviceaccount.workloadidentity.gcp.livewyer.io/%s" $id) }}
{{- range $key, $value := $annotations }}
{{ $key }}: "{{ $value }}"
{{- end }}
labels:
gcp.livewyer.io/workloadidentity: {{ $id }}
workloadidentity.gcp.livewyer.io/serviceaccount: {{ $id }}
{{- range $key, $value := $labels }}
{{ $key }}: "{{ $value }}"
{{- end }}
spec:
{{- if $spec.providerConfigRef }}
providerConfigRef: {{ toJson $spec.providerConfigRef }}
{{- end }}
{{- if $spec.deletionPolicy }}
deletionPolicy: {{ $spec.deletionPolicy }}
{{- end }}
{{- if $spec.managementPolicies }}
managementPolicies: {{ toJson $spec.managementPolicies }}
{{- end }}
{{- if $spec.publishConnectionDetailsTo }}
publishConnectionDetailsTo: {{ toJson $spec.publishConnectionDetailsTo }}
{{- end }}
{{- if $spec.writeConnectionSecretsToNamespace }}
writeConnectionSecretsToNamespace: {{ $spec.writeConnectionSecretsToNamespace }}
{{- end }}
forProvider:
displayName: {{ $id }}
project: {{ $spec.forProvider.projectId }}
createIgnoreAlreadyExists: true
---
apiVersion: cloudplatform.gcp.m.upbound.io/v1beta1
kind: Project
metadata:
name: {{ $id }}
namespace: {{ $ns }}
annotations:
{{ setResourceNameAnnotation (printf "project.workloadidentity.gcp.livewyer.io/%s" $spec.forProvider.projectId) }}
crossplane.io/external-name: {{ $spec.forProvider.projectId }}
{{- range $key, $value := $annotations }}
{{ $key }}: "{{ $value }}"
{{- end }}
labels:
gcp.livewyer.io/workloadidentity: {{ $id }}
workloadidentity.gcp.livewyer.io/project: {{ $spec.forProvider.projectId }}
{{- range $key, $value := $labels }}
{{ $key }}: "{{ $value }}"
{{- end }}
spec:
managementPolicies: ["Observe"]
forProvider:
projectId: {{ $spec.forProvider.projectId }}
---
apiVersion: cloudplatform.gcp.m.upbound.io/v1beta1
kind: ServiceAccountIAMMember
metadata:
name: {{ $id }}
namespace: {{ $ns }}
annotations:
{{ setResourceNameAnnotation (printf "serviceaccountiammember.workloadidentity.gcp.livewyer.io/%s" $id) }}
{{- range $key, $value := $annotations }}
{{ $key }}: "{{ $value }}"
{{- end }}
labels:
gcp.livewyer.io/workloadidentity: {{ $id }}
workloadidentity.gcp.livewyer.io/serviceaccountiammember: {{ $id }}
{{- range $key, $value := $labels }}
{{ $key }}: "{{ $value }}"
{{- end }}
spec:
{{- if $spec.providerConfigRef }}
providerConfigRef: {{ toJson $spec.providerConfigRef }}
{{- end }}
{{- if $spec.deletionPolicy }}
deletionPolicy: {{ $spec.deletionPolicy }}
{{- end }}
{{- if $spec.managementPolicies }}
managementPolicies: {{ toJson $spec.managementPolicies }}
{{- end }}
{{- if $spec.publishConnectionDetailsTo }}
publishConnectionDetailsTo: {{ toJson $spec.publishConnectionDetailsTo }}
{{- end }}
{{- if $spec.writeConnectionSecretsToNamespace }}
writeConnectionSecretsToNamespace: {{ $spec.writeConnectionSecretsToNamespace }}
{{- end }}
forProvider:
serviceAccountIdRef:
name: {{ $id }}
namespace: {{ $ns }}
role: roles/iam.workloadIdentityUser
member: {{ printf "principal://iam.googleapis.com/projects/%s/locations/global/workloadIdentityPools/%s.svc.id.goog/subject/ns/%s/sa/%s" (dig "resources" (printf "project.workloadidentity.gcp.livewyer.io/%s" $spec.forProvider.projectId) "resource" "status" "atProvider" "number" "" $.observed) $spec.forProvider.projectId (default $ns $spec.forProvider.serviceAccountNamespace) (default $id $spec.forProvider.serviceAccountName) }}
---
{{- range $i, $projectRoles := (concat (list (dict "projectId"
$spec.forProvider.projectId "roles" $spec.forProvider.roles))
(default (list) $spec.forProvider.additionalProjects)) }}
{{- range $role := (index $projectRoles "roles") }}
{{- $roleId := printf "%s-%d-%s-%s" $id $i (lower (index
$projectRoles "projectId")) (lower (trimPrefix "roles/" $role)) }}
---
apiVersion: cloudplatform.gcp.m.upbound.io/v1beta1
kind: ProjectIAMMember
metadata:
name: {{ $roleId }}
namespace: {{ $ns }}
annotations:
{{ setResourceNameAnnotation (printf "projectiammember.workloadidentity.gcp.livewyer.io/%s" $roleId) }}
{{- range $key, $value := $annotations }}
{{ $key }}: "{{ $value }}"
{{- end }}
labels:
gcp.livewyer.io/workloadidentity: {{ $id }}
workloadidentity.gcp.livewyer.io/projectiammember: {{ $roleId }}
{{- range $key, $value := $labels }}
{{ $key }}: "{{ $value }}"
{{- end }}
spec:
{{- if $spec.providerConfigRef }}
providerConfigRef: {{ toJson $spec.providerConfigRef }}
{{- end }}
{{- if $spec.deletionPolicy }}
deletionPolicy: {{ $spec.deletionPolicy }}
{{- end }}
{{- if $spec.managementPolicies }}
managementPolicies: {{ toJson $spec.managementPolicies }}
{{- end }}
{{- if $spec.publishConnectionDetailsTo }}
publishConnectionDetailsTo: {{ toJson $spec.publishConnectionDetailsTo }}
{{- end }}
{{- if $spec.writeConnectionSecretsToNamespace }}
writeConnectionSecretsToNamespace: {{ $spec.writeConnectionSecretsToNamespace }}
{{- end }}
forProvider:
project: {{ index $projectRoles "projectId" }}
role: {{ $role }}
member: {{ printf "serviceAccount:%s@%s.iam.gserviceaccount.com" $id $spec.forProvider.projectId }}
---
{{- end }}
{{- end }}
{{- if $spec.forProvider.serviceAccountName }}
---
apiVersion: kubernetes.m.crossplane.io/v1alpha1
kind: Object
metadata:
name: {{ $spec.forProvider.serviceAccountName }}
namespace: {{ $ns }}
annotations:
{{ setResourceNameAnnotation (printf "serviceaccount.workloadidentity.k8s.livewyer.io/%s" $spec.forProvider.serviceAccountName) }}
iam.gke.io/gcp-service-account: {{ printf "%s@%s.iam.gserviceaccount.com" $id $spec.forProvider.projectId }}
{{- range $key, $value := $annotations }}
{{ $key }}: "{{ $value }}"
{{- end }}
labels:
gcp.livewyer.io/workloadidentity: {{ $id }}
workloadidentity.gcp.livewyer.io/serviceaccount: {{ $spec.forProvider.serviceAccountName }}
{{- range $key, $value := $labels }}
{{ $key }}: "{{ $value }}"
{{- end }}
spec:
forProvider:
manifest:
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ $spec.forProvider.serviceAccountName }}
namespace: {{ default $ns $spec.forProvider.serviceAccountNamespace }}
annotations:
iam.gke.io/gcp-service-account: {{ printf "%s@%s.iam.gserviceaccount.com" $id $spec.forProvider.projectId }}
{{- range $key, $value := $annotations }}
{{ $key }}: "{{ $value }}"
{{- end }}
labels:
gcp.livewyer.io/workloadidentity: {{ $id }}
workloadidentity.gcp.livewyer.io/serviceaccount: {{ $spec.forProvider.serviceAccountName }}
{{- range $key, $value := $labels }}
{{ $key }}: "{{ $value }}"
{{- end }}
automountServiceAccountToken: {{ default true $spec.forProvider.automountServiceAccountToken }}
---
{{- end }}
---
apiVersion: {{ .observed.composite.resource.apiVersion }}
kind: {{ .observed.composite.resource.kind }}
metadata:
name: {{ $id }}
namespace: {{ $ns }}
labels:
gcp.livewyer.io/workloadidentity: {{ $id }}
status:
atProvider:
serviceAccount: {{ toJson (getComposedResource . (printf "serviceaccount.workloadidentity.gcp.livewyer.io/%s" $id)).status.atProvider }}
serviceAccountIamMember: {{ toJson (getComposedResource . (printf "serviceaccountiammember.workloadidentity.gcp.livewyer.io/%s" $id)).status.atProvider }}
roles:
{{- range $i, $projectRoles := (concat (list (dict "projectId" $spec.forProvider.projectId "roles" $spec.forProvider.roles)) (default (list) $spec.forProvider.additionalProjects)) }}
{{- range $role := (index $projectRoles "roles") }}
{{- $roleId := printf "%s-%d-%s-%s" $id $i (lower (index $projectRoles "projectId")) (lower (trimPrefix "roles/" $role)) }}
- {{ $roleId }}: {{ toJson (dig "resources" (printf "projectiammember.workloadidentity.gcp.livewyer.io/%s" $roleId) "resource" "status" "atProvider" (dict) $.observed) }}
{{- end }}
{{- end }}
---
kind: GoTemplate
source: Inline
- step: automatically-detect-ready-composed-resources
functionRef:
name: upbound-function-auto-ready