Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
New annotation to allow injection of custom Vault image (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
asaintsever authored Feb 9, 2021
1 parent 9028f65 commit ea5fb8f
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 39 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog for Vault Sidecar Injector

## Release v7.1.0 - TO_BE_RELEASED

A new `sidecar.vault.talend.org/vault-image` annotation has been added to override the default injected image. Refer to the [samples](samples) for a working example.

**Added**

- [VSI #43](https://github.com/Talend/vault-sidecar-injector/pull/43) - New annotation to allow injection of custom Vault image

## Release v7.0.2 - 2020-11-09

**Changed**
Expand Down
2 changes: 1 addition & 1 deletion VERSION_CHART
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.1.1
4.2.0
2 changes: 1 addition & 1 deletion VERSION_RELEASE
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.0.2
7.1.0
2 changes: 1 addition & 1 deletion VERSION_VSI
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.0.1
7.1.0
8 changes: 4 additions & 4 deletions cmd/vaultinjector-env/main.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 Talend - www.talend.com
// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -47,8 +47,8 @@ func init() {

// Program accepts following env vars:
//
// VSI_ENV_LOG_JSON true/false (default) Log as JSON
// VSI_ENV_LOG_LEVEL 0 to 6 (default: 3 fo warning) Log level
// VSI_ENV_LOG_JSON true/false (default) Log as JSON
// VSI_ENV_LOG_LEVEL 0 to 6 (default: 3) Log level (3 for warning, 6 to trace everything)
//
func main() {
var entrypointCmd []string
Expand Down Expand Up @@ -103,7 +103,7 @@ func main() {
// Replace current process with original one, providing env vars (including new ones from fetched secrets)
err = syscall.Exec(binary, entrypointCmd, env)
if err != nil {
log.Panicln("failed to exec process", entrypointCmd, err.Error())
log.Fatalln("failed to exec process", entrypointCmd, err.Error())
}
}

Expand Down
3 changes: 2 additions & 1 deletion doc/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Following annotations in requesting pods are supported:

| Annotation | (M)andatory / (O)ptional | Apply to mode | Default Value | Supported Values | Description |
|---------------------------------------|--------------------------|-----------------|----------------------|--------------------------------|-------------|
| `sidecar.vault.talend.org/inject` | M | N/A | | "true" / "on" / "yes" / "y" | Ask for sidecar injection to get secrets from Vault |
| `sidecar.vault.talend.org/inject` | M | N/A | | "true" / "on" / "yes" / "y" | Ask for injection to get secrets from Vault |
| `sidecar.vault.talend.org/vault-image` | O | N/A | "<`injectconfig.vault.image.path` Helm value>:<`injectconfig.vault.image.tag` Helm value>" | Any image with Vault installed | The image to be injected in your pod |
| `sidecar.vault.talend.org/auth` | O | N/A | "kubernetes" | "kubernetes" / "approle" | Vault Auth Method to use. **Static secrets only supports "kubernetes" authentication method** |
| `sidecar.vault.talend.org/mode` | O | N/A | "secrets" | "secrets" / "proxy" / "job" / Comma-separated values (eg "secrets,proxy") | Enable provided mode(s). **Note: `secrets` mode will be enabled if you only set `job` mode** |
| `sidecar.vault.talend.org/notify` | O | secrets | "" | Comma-separated strings | List of commands to notify application/service of secrets change, one per secrets path. **Usage context: dynamic secrets only** |
Expand Down
15 changes: 8 additions & 7 deletions doc/announcements/HashiCorp-Vault-Agent-Injector.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Vault Sidecar Injector vs HashiCorp Vault Agent Injector - Features Comparison

*March 2020, [Post by Alain Saint-Sever, Principal Cloud Software Architect (@alstsever)](https://twitter.com/alstsever)*
*March 2020 (with [updates](#changes-since-comparison)), [Post by Alain Saint-Sever, Principal Cloud Software Architect (@alstsever)](https://twitter.com/alstsever)*

- [Vault Sidecar Injector vs HashiCorp Vault Agent Injector - Features Comparison](#vault-sidecar-injector-vs-hashicorp-vault-agent-injector---features-comparison)
- [Intro](#intro)
Expand All @@ -10,6 +10,7 @@
- [HashiCorp Vault Agent Injector installation](#hashicorp-vault-agent-injector-installation)
- [Test Workloads](#test-workloads)
- [Features Comparison](#features-comparison)
- [Changes since comparison](#changes-since-comparison)

## Intro

Expand Down Expand Up @@ -135,21 +136,21 @@ Features comparison `Vault Sidecar Injector` vs `HashiCorp Vault Agent Injector`
| Custom Vault Agent config | **Not possible** | By providing K8S ConfigMap with custom Vault Agent config + using annotation to load config *(`vault.hashicorp.com/agent-configmap`)* |
| Vault AppRole Auth support | At pod level *(using annotation)* | By providing K8S ConfigMap with custom Vault Agent config + using annotation to load config *(`vault.hashicorp.com/agent-configmap`)* |
| Secrets volume mount path | Any path associated to the `secrets` Volume | Cannot be changed *(set to `/vault/secrets`)* |
| Shared secrets volume| Injection of In-memory Volume **only** if not defined. VolumeMount is not injected if not defined ***(1)*** | Injection of both In-memory Volume and VolumeMount. **Failure** if `vault-secrets` Volume already defined |
| Shared secrets volume| Injection of In-memory Volume **only** if not defined. VolumeMount is not injected if not defined ***([1](#changes-since-comparison))*** | Injection of both In-memory Volume and VolumeMount. **Failure** if `vault-secrets` Volume already defined |
| Resources (CPU, mem) for injected container(s) | At webhook level *(helm chart values)* | At pod level *(default values or custom via annotations)* |
| Resources (CPU, mem) for webhook | Using Helm chart values | Using Helm chart values |
| Vault server to use | At webhook level *(helm chart value)* | Both at webhook *(helm chart value)* and pod levels *(via annotation)* |
| Vault Agent's check of Vault's TLS cert | At webhook level *(helm chart value)* | At pod level *(using annotation)* |
|Vault Agent image| At webhook level *(helm chart value)* | Both at webhook *(helm chart value)* and pod levels *(via annotation)* |
|Vault Agent image| At webhook level *(helm chart value)* ***([2](#changes-since-comparison))*** | Both at webhook *(helm chart value)* and pod levels *(via annotation)* |

Most of the differences are less the result of technical choice than philosophical ones: the Vault Sidecar Injector is more "user friendly" in this regard by easily giving access to Vault proxy mode or other technical features through a simple annotation, where the same capabilities on HashiCorp's injector will require the user to provide a complete Vault Agent config wrapped into a Kubernetes ConfigMap. This distinct approach can also be seen with Vault Sidecar Injector's modes that completely relieve the user from knowing whether he needs an init container or a sidecar or both of them to handle a use case. On the other end, with the HashiCorp's injector, the user has control over the injected content and this "complexity" allows for greater flexibility.

**The major advantage brought by the Vault Sidecar Injector lies in how it supports dynamic secrets in Kubernetes Jobs, a feature currently not properly implemented on HashiCorp side.**

Future Vault Sidecar Injector releases will continue focusing on a feature-oriented, non-technical path to make injector usage as seamless as possible. Results from this comparison test show that there is room for some improvements on volume management that will be taking care of soon. Stay tuned !

<hr>
## Changes since comparison

**Changes since comparison:**

> *(1), June 2020: as of Vault Sidecar Injector release 7.0.0, volumeMount is also injected if not defined*
> ***(1)**, June 2020: as of Vault Sidecar Injector release 7.0.0, volumeMount is also injected if not defined*
>
> ***(2)**, February 2021: as of Vault Sidecar Injector release 7.1.0, you can also select the image to inject at pod level (using an annotation)*
25 changes: 25 additions & 0 deletions pkg/config/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package config

const (
//--- Init Containers defined in our injection config
VaultAgentInitContainerName = "tvsi-vault-agent-init"
VSIEnvInitContainerName = "tvsi-env-init"

//--- Containers defined in our injection config
JobMonitoringContainerName = "tvsi-job-babysitter"
VaultAgentContainerName = "tvsi-vault-agent"
)
15 changes: 8 additions & 7 deletions pkg/context/constants.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 Talend - www.talend.com
// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -17,12 +17,13 @@ package context
const (
//--- Vault Sidecar Injector annotation keys (without prefix)
// Input annotations (set on incoming manifest)
VaultInjectorAnnotationInjectKey = "inject" // Mandatory
VaultInjectorAnnotationAuthMethodKey = "auth" // Optional. Vault Auth Method to use: kubernetes (default) or approle
VaultInjectorAnnotationModeKey = "mode" // Optional. Comma-separated list of mode(s) to enable.
VaultInjectorAnnotationRoleKey = "role" // Optional. To explicitly provide Vault role to use
VaultInjectorAnnotationSATokenKey = "sa-token" // Optional. Full path to service account token used for Vault Kubernetes authentication
VaultInjectorAnnotationWorkloadKey = "workload" // Optional and deprecated. If set to "job", supplementary container and signaling mechanism will also be injected to properly handle k8s job
VaultInjectorAnnotationInjectKey = "inject" // Mandatory
VaultInjectorAnnotationVaultImageKey = "vault-image" // Optional. Image to inject
VaultInjectorAnnotationAuthMethodKey = "auth" // Optional. Vault Auth Method to use: kubernetes (default) or approle
VaultInjectorAnnotationModeKey = "mode" // Optional. Comma-separated list of mode(s) to enable.
VaultInjectorAnnotationRoleKey = "role" // Optional. To explicitly provide Vault role to use
VaultInjectorAnnotationSATokenKey = "sa-token" // Optional. Full path to service account token used for Vault Kubernetes authentication
VaultInjectorAnnotationWorkloadKey = "workload" // Optional and deprecated. If set to "job", supplementary container and signaling mechanism will also be injected to properly handle k8s job
// Output annotation (set by VSI webhook)
VaultInjectorAnnotationStatusKey = "status" // Not to be set by requesting pods: set by the Webhook Admission Controller if injection ok
)
Expand Down
3 changes: 2 additions & 1 deletion pkg/context/types.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 Talend - www.talend.com
// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@ package context
// InjectionContext : struct to carry computed placeholders' values and context info for current injection
type InjectionContext struct {
K8sDefaultSATokenVolumeName string
VaultImage string
VaultInjectorSATokenVolumeName string
VaultAuthMethod string
VaultRole string
Expand Down
8 changes: 5 additions & 3 deletions pkg/mode/job/constants.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 Talend - www.talend.com
// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -14,10 +14,12 @@

package job

import "talend/vault-sidecar-injector/pkg/config"

const (
//--- Job handling - Temporary mechanism until KEP https://github.com/kubernetes/enhancements/blob/master/keps/sig-apps/sidecarcontainers.md is implemented (and we migrate on appropriate version of k8s)
jobMonitoringContainerName = "tvsi-job-babysitter" // Name of our specific sidecar container to inject in submitted jobs
jobListenerContainerName = "tvsi-vault-agent" // Name of the container listening for signal from job monitoring container
jobMonitoringContainerName = config.JobMonitoringContainerName // Name of our specific sidecar container to inject in submitted jobs
jobListenerContainerName = config.VaultAgentContainerName // Name of the container listening for signal from job monitoring container

//--- Job handling env vars
jobContainerNameEnv = "VSI_JOB_CNT_NAME" // Env var for name of the app job's container
Expand Down
8 changes: 5 additions & 3 deletions pkg/mode/proxy/constants.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 Talend - www.talend.com
// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -14,14 +14,16 @@

package proxy

import "talend/vault-sidecar-injector/pkg/config"

const (
//--- Vault Sidecar Injector modes annotation keys (without prefix)
vaultInjectorAnnotationProxyPortKey = "proxy-port" // Optional. Port assigned to local Vault proxy.
)

const (
proxyContainerName = "tvsi-vault-agent" // Name of our proxy container to inject
vaultProxyDefaultPort = "8200" // Default port to access local Vault proxy
proxyContainerName = config.VaultAgentContainerName // Name of our proxy container to inject
vaultProxyDefaultPort = "8200" // Default port to access local Vault proxy
)

const (
Expand Down
18 changes: 10 additions & 8 deletions pkg/mode/secrets/constants.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 Talend - www.talend.com
// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -14,6 +14,8 @@

package secrets

import "talend/vault-sidecar-injector/pkg/config"

const (
//--- Vault Sidecar Injector modes annotation keys (without prefix)
vaultInjectorAnnotationSecretsPathKey = "secrets-path" // Optional. Full path, e.g.: "secret/<some value>", "aws/creds/<some role>", ... Several values separated by ','.
Expand All @@ -26,13 +28,13 @@ const (
)

const (
secretsContainerName = "tvsi-vault-agent" // Name of our secrets container to inject
secretsInitContainerName = "tvsi-vault-agent-init" // Name of our secrets init container to inject
secretsEnvInitContainerName = "tvsi-env-init" // Name of our env process init container to inject
templateAppSvcDefaultDestination = "secrets.properties" // Default secrets destination
vaultDefaultSecretsEnginePath = "secret" // Default path for Vault K/V Secrets Engine if no 'secrets-path' annotation
secretsAnnotationSeparator = "," // Generic separator for secrets annotations' values
secretsAnnotationTemplateSeparator = "---" // Separator for secrets templates annotation's values
secretsContainerName = config.VaultAgentContainerName // Name of our secrets container to inject
secretsInitContainerName = config.VaultAgentInitContainerName // Name of our secrets init container to inject
secretsEnvInitContainerName = config.VSIEnvInitContainerName // Name of our env process init container to inject
templateAppSvcDefaultDestination = "secrets.properties" // Default secrets destination
vaultDefaultSecretsEnginePath = "secret" // Default path for Vault K/V Secrets Engine if no 'secrets-path' annotation
secretsAnnotationSeparator = "," // Generic separator for secrets annotations' values
secretsAnnotationTemplateSeparator = "---" // Separator for secrets templates annotation's values
)

const (
Expand Down
3 changes: 2 additions & 1 deletion pkg/webhook/types.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 Talend - www.talend.com
// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -29,6 +29,7 @@ type VaultInjector struct {
// Supported annotations (modes' annotations will be appended to this array)
var vaultInjectorAnnotationKeys = []string{
ctx.VaultInjectorAnnotationInjectKey,
ctx.VaultInjectorAnnotationVaultImageKey,
ctx.VaultInjectorAnnotationAuthMethodKey,
ctx.VaultInjectorAnnotationModeKey,
ctx.VaultInjectorAnnotationRoleKey,
Expand Down
12 changes: 11 additions & 1 deletion pkg/webhook/update-pod.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2019-2020 Talend - www.talend.com
// Copyright © 2019-2021 Talend - www.talend.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -20,6 +20,7 @@ import (
"strconv"
"strings"

"talend/vault-sidecar-injector/pkg/config"
ctx "talend/vault-sidecar-injector/pkg/context"
m "talend/vault-sidecar-injector/pkg/mode"
"talend/vault-sidecar-injector/pkg/mode/job"
Expand Down Expand Up @@ -84,6 +85,7 @@ func (vaultInjector *VaultInjector) computeContext(podContainers []corev1.Contai

klog.Infof("Modes status: %+v", modesStatus)

vaultImage := annotations[vaultInjector.VaultInjectorAnnotationsFQ[ctx.VaultInjectorAnnotationVaultImageKey]]
vaultAuthMethod := strings.ToLower(annotations[vaultInjector.VaultInjectorAnnotationsFQ[ctx.VaultInjectorAnnotationAuthMethodKey]])
vaultRole := annotations[vaultInjector.VaultInjectorAnnotationsFQ[ctx.VaultInjectorAnnotationRoleKey]]
vaultSATokenPath := annotations[vaultInjector.VaultInjectorAnnotationsFQ[ctx.VaultInjectorAnnotationSATokenKey]]
Expand Down Expand Up @@ -149,6 +151,7 @@ func (vaultInjector *VaultInjector) computeContext(podContainers []corev1.Contai

return &ctx.InjectionContext{
K8sDefaultSATokenVolumeName: k8sSaSecretsVolName,
VaultImage: vaultImage,
VaultInjectorSATokenVolumeName: vaultInjectorSaSecretsVolName,
VaultAuthMethod: vaultAuthMethod,
VaultRole: vaultRole,
Expand Down Expand Up @@ -243,6 +246,13 @@ func (vaultInjector *VaultInjector) addContainer(podContainers []corev1.Containe
}
}

// Check if custom Vault image is provided and, if so, update image for relevant containers
if context.VaultImage != "" {
if (container.Name == config.VaultAgentInitContainerName) || (container.Name == config.VaultAgentContainerName) {
container.Image = context.VaultImage
}
}

value = container
path := basePath

Expand Down
Loading

0 comments on commit ea5fb8f

Please sign in to comment.