First steps in Crossplane-Vault integration
This commit is contained in:
parent
bcb2bd28d7
commit
e798564692
@ -39,7 +39,8 @@
|
|||||||
localApplication(
|
localApplication(
|
||||||
name,
|
name,
|
||||||
path="",
|
path="",
|
||||||
namespace="") ::
|
namespace="",
|
||||||
|
nonHelmApp=false) ::
|
||||||
{
|
{
|
||||||
apiVersion: "argoproj.io/v1alpha1",
|
apiVersion: "argoproj.io/v1alpha1",
|
||||||
kind: "Application",
|
kind: "Application",
|
||||||
@ -56,7 +57,7 @@
|
|||||||
path: if path == "" then std.join('/', ['charts', name]) else path,
|
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
|
// I _think_ every locally-defined chart is going to have a `values.yaml`, but we can make this
|
||||||
// parameterized if desired
|
// parameterized if desired
|
||||||
helm: {
|
[if nonHelmApp != true then "helm"]: {
|
||||||
valueFiles: ['values.yaml']
|
valueFiles: ['values.yaml']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,49 @@
|
|||||||
// https://docs.crossplane.io/v1.15/software/install/#installed-deployments
|
// https://docs.crossplane.io/v1.15/software/install/#installed-deployments
|
||||||
local appDef = import './app-definitions.libsonnet';
|
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(
|
appDef.helmApplication(
|
||||||
name="crossplane",
|
name="crossplane",
|
||||||
sourceRepoUrl="https://charts.crossplane.io/stable",
|
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