First steps in Crossplane-Vault integration
This commit is contained in:
parent
bcb2bd28d7
commit
e798564692
@ -39,7 +39,8 @@
|
||||
localApplication(
|
||||
name,
|
||||
path="",
|
||||
namespace="") ::
|
||||
namespace="",
|
||||
nonHelmApp=false) ::
|
||||
{
|
||||
apiVersion: "argoproj.io/v1alpha1",
|
||||
kind: "Application",
|
||||
@ -56,7 +57,7 @@
|
||||
path: if path == "" then std.join('/', ['charts', name]) else path,
|
||||
// I _think_ every locally-defined chart is going to have a `values.yaml`, but we can make this
|
||||
// parameterized if desired
|
||||
helm: {
|
||||
[if nonHelmApp != true then "helm"]: {
|
||||
valueFiles: ['values.yaml']
|
||||
}
|
||||
},
|
||||
|
@ -1,6 +1,49 @@
|
||||
// https://docs.crossplane.io/v1.15/software/install/#installed-deployments
|
||||
local appDef = import './app-definitions.libsonnet';
|
||||
|
||||
// Installation of Vault Provider is left manually, since it relies on secret creation:
|
||||
// https://github.com/upbound/provider-vault
|
||||
//
|
||||
// Also required created a role to bind to the ServiceAccount:
|
||||
//
|
||||
// apiVersion: rbac.authorization.k8s.io/v1
|
||||
// kind: ClusterRoleBinding
|
||||
// metadata:
|
||||
// name: vault-provider-role-binding
|
||||
// namespace: crossplane-system
|
||||
// roleRef:
|
||||
// apiGroup: rbac.authorization.k8s.io
|
||||
// kind: ClusterRole
|
||||
// name: vault-provider-role
|
||||
// subjects:
|
||||
// - kind: ServiceAccount
|
||||
// name: provider-vault-b61923ede364
|
||||
// namespace: crossplane-system
|
||||
// ---
|
||||
// apiVersion: rbac.authorization.k8s.io/v1
|
||||
// kind: ClusterRole
|
||||
// metadata:
|
||||
// name: vault-provider-role
|
||||
// namespace: crossplane-system
|
||||
// rules:
|
||||
// - apiGroups:
|
||||
// - identity.vault.upbound.io
|
||||
// resources:
|
||||
// - mfaoktas
|
||||
// - groupmembergroupidsidses
|
||||
// - groupmemberentityidsidses
|
||||
// verbs:
|
||||
// - get
|
||||
// - list
|
||||
// - watch
|
||||
// - apiGroups:
|
||||
// - mfa.vault.upbound.io
|
||||
// resources:
|
||||
// - oktas
|
||||
// verbs:
|
||||
// - get
|
||||
// - list
|
||||
// - watch
|
||||
appDef.helmApplication(
|
||||
name="crossplane",
|
||||
sourceRepoUrl="https://charts.crossplane.io/stable",
|
||||
|
3
app-of-apps/vault-crossplane-integration.jsonnet
Normal file
3
app-of-apps/vault-crossplane-integration.jsonnet
Normal file
@ -0,0 +1,3 @@
|
||||
local appDef = import './app-definitions.libsonnet';
|
||||
|
||||
appDef.localApplication(name="vault-crossplane-integration", nonHelmApp=true)
|
177
charts/vault-crossplane-integration/base-app-infra.yaml
Normal file
177
charts/vault-crossplane-integration/base-app-infra.yaml
Normal file
@ -0,0 +1,177 @@
|
||||
apiVersion: apiextensions.crossplane.io/v1
|
||||
kind: CompositeResourceDefinition
|
||||
metadata:
|
||||
name: xbaseapplicationinfrastructures.scubbo.org
|
||||
spec:
|
||||
group: scubbo.org
|
||||
names:
|
||||
kind: xBaseApplicationInfrastructure
|
||||
plural: xbaseapplicationinfrastructures
|
||||
claimNames:
|
||||
kind: BaseAppInfra
|
||||
plural: baseappinfras
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
referenceable: true
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
appName:
|
||||
type: string
|
||||
---
|
||||
# Sources for the Vault resources are here:
|
||||
# https://developer.hashicorp.com/vault/tutorials/kubernetes/vault-secrets-operator#configure-vault
|
||||
apiVersion: apiextensions.crossplane.io/v1
|
||||
kind: Composition
|
||||
metadata:
|
||||
name: base-application-infrastructure
|
||||
spec:
|
||||
compositeTypeRef:
|
||||
apiVersion: scubbo.org/v1alpha1
|
||||
kind: xBaseApplicationInfrastructure
|
||||
resources:
|
||||
- name: vault-role
|
||||
base:
|
||||
apiVersion: kubernetes.vault.upbound.io/v1alpha1
|
||||
kind: AuthBackendRole
|
||||
spec:
|
||||
providerConfigRef:
|
||||
name: vault-provider-config
|
||||
forProvider:
|
||||
audience: vault
|
||||
boundServiceAccountNames:
|
||||
- default
|
||||
tokenTtl: 86400
|
||||
patches:
|
||||
- type: FromCompositeFieldPath
|
||||
# https://docs.crossplane.io/latest/concepts/composite-resources/#claim-namespace-label
|
||||
fromFieldPath: metadata.labels["crossplane.io/claim-namespace"]
|
||||
toFieldPath: spec.forProvider.boundServiceAccountNamespaces
|
||||
transforms:
|
||||
- type: string
|
||||
string:
|
||||
type: Format
|
||||
fmt: "[\"%s\"]"
|
||||
- type: convert
|
||||
convert:
|
||||
toType: array
|
||||
format: json
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.appName
|
||||
toFieldPath: spec.forProvider.roleName
|
||||
transforms:
|
||||
- type: string
|
||||
string:
|
||||
type: Format
|
||||
fmt: "vault-secrets-operator-%s-role"
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.appName
|
||||
toFieldPath: spec.forProvider.tokenPolicies
|
||||
transforms:
|
||||
- type: string
|
||||
string:
|
||||
type: Format
|
||||
fmt: "[\"vault-secrets-operator-%s-policy\"]"
|
||||
- type: convert
|
||||
convert:
|
||||
toType: array
|
||||
format: json
|
||||
|
||||
- name: vault-secrets-mount
|
||||
base:
|
||||
apiVersion: vault.vault.upbound.io/v1alpha1
|
||||
kind: Mount
|
||||
spec:
|
||||
providerConfigRef:
|
||||
name: vault-provider-config
|
||||
forProvider:
|
||||
type: kv-v2
|
||||
patches:
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.appName
|
||||
toFieldPath: spec.forProvider.path
|
||||
transforms:
|
||||
- type: string
|
||||
string:
|
||||
type: Format
|
||||
fmt: "app-%s-kv"
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.appName
|
||||
toFieldPath: spec.forProvider.description
|
||||
transforms:
|
||||
- type: string
|
||||
string:
|
||||
type: Format
|
||||
fmt: "KV storage for app %s"
|
||||
|
||||
- name: vault-policy
|
||||
base:
|
||||
apiVersion: vault.vault.upbound.io/v1alpha1
|
||||
kind: Policy
|
||||
spec:
|
||||
providerConfigRef:
|
||||
name: vault-provider-config
|
||||
forProvider: {}
|
||||
patches:
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.appName
|
||||
toFieldPath: spec.forProvider.name
|
||||
transforms:
|
||||
- type: string
|
||||
string:
|
||||
type: Format
|
||||
fmt: "vault-secrets-operator-%s-policy"
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.appName
|
||||
toFieldPath: spec.forProvider.policy
|
||||
transforms:
|
||||
- type: string
|
||||
string:
|
||||
type: Format
|
||||
fmt: "path \"app-%s-kv/*\" {capabilities=[\"read\"]}"
|
||||
|
||||
# Note that this is an `Object` created by provider-kubernetes, not by provider-vault
|
||||
- name: vault-auth
|
||||
base:
|
||||
apiVersion: kubernetes.crossplane.io/v1alpha2
|
||||
kind: Object
|
||||
spec:
|
||||
providerConfigRef:
|
||||
name: kubernetes-provider
|
||||
forProvider:
|
||||
manifest:
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultAuth
|
||||
spec:
|
||||
method: kubernetes
|
||||
mount: kubernetes # Hard-coded - this is what I used in my setup, but this could be customizable
|
||||
kubernetes:
|
||||
serviceAccount: default
|
||||
audiences:
|
||||
- vault
|
||||
patches:
|
||||
# The Vault Role created earlier in this Composition
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.appName
|
||||
toFieldPath: spec.forProvider.manifest.spec.kubernetes.role
|
||||
transforms:
|
||||
- type: string
|
||||
string:
|
||||
type: Format
|
||||
fmt: "vault-secrets-operator-%s-role"
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: spec.appName
|
||||
toFieldPath: spec.forProvider.manifest.metadata.name
|
||||
transforms:
|
||||
- type: string
|
||||
string:
|
||||
type: Format
|
||||
fmt: "vault-auth-%s"
|
||||
- type: FromCompositeFieldPath
|
||||
fromFieldPath: metadata.labels["crossplane.io/claim-namespace"]
|
||||
toFieldPath: spec.forProvider.manifest.metadata.namespace
|
Loading…
x
Reference in New Issue
Block a user