Argo Workflows is an open source project that is container-native and uses Kubernetes to run its workflow steps. Argo enables users to create a multi-step workflow that can orchestrate parallel jobs and capture the dependencies between tasks. The framework allows for parameterization and conditional execution, passing values between steps, timeouts, retry logic, recursion, flow control, and looping.
HashiCorp Vault is a secrets management tool specifically designed to control access to sensitive credentials in a low-trust environment. Vault provides a unified interface to any secret while providing tight access control and recording a detailed audit log.
Argo gives you a convenient way to access Red Hat OpenShift secrets, but what if your company uses Vault instead? I'll walk you through how to do this and package it up into a Helm chart for easy installation and reuse.
Installation
Installing Argo and Vault is fairly simple. Argo has an install YAML file that includes necessary resources to run Argo. Check out GitHub for additional information.
Vault has a Helm chart for installation. This guide will walk you through the installation via Helm chart and help you set up what’s needed to access Vault from Red Hat OpenShift. It’s also a good idea to look at this tutorial that walks you through injecting secrets via Vault Sidecar.
The use of the Vault Agent Sidecar Injector allows containers within the pod to consume Vault secrets without being Vault aware. It does so by altering pod specifications to include Vault Agent containers that render Vault secrets to a shared memory volume. This approach works especially well for secrets that are dynamic and frequently updated.
Vault Integration
Git Input Artifact
Argo Workflows have a very convenient feature to easily get source code from Git, called GitArtifact. GitArtifact allows for basic auth or SSH private key access. If you have your credentials stored in an OpenShift secret, you could do the following:
templates:
- name: git-clone
inputs:
artifacts:
- name: argo-source
path: "{{workflow.parameters.git-repo-path}}"
git:
repo: "{{workflow.parameters.git-repo-url}}"
revision: "{{workflow.parameters.git-repo-revision}}"
usernameSecret:
name: "{{workflow.parameters.git-secret-name}}"
key: username
passwordSecret:
name: "{{workflow.parameters.git-secret-name}}"
key: password
container:
image: alpine/git
command: [sh, -c]
args: ["git status && ls && cat VERSION"]
workingDir: "{{workflow.parameters.git-repo-path}}"
However, what if your credentials are stored in Vault, and you cannot use basic auth or SSH?
Argo Git Step
Since Argo does not have built-in support for Vault, we cannot use the GitArtifact described above. Lucky for us, we can take advantage of Vault’s ability to mount files on the pod filesystem. If your Vault secret is just a Git token, you could do the following:
templates:
- name: git-clone
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "git-creds"
vault.hashicorp.com/secret-volume-path: "/home"
vault.hashicorp.com/agent-inject-secret-token: "secret/git-creds"
vault.hashicorp.com/agent-inject-template-token: |
{{- with secret "secret/git-creds" -}}
{{ .Data.data.token }}
{{- end }}
container:
image: alpine/git
command: [sh, -c]
args: ["git clone -b {{workflow.parameters.git-repo-revision}} https://`cat /home/token`@{{workflow.parameters.git-repo-url}} . && git status && ls && cat README.md
"]
workingDir: /src
Here we write the Git token from Vault to the `/home/token` file and cat the file out when cloning the repo. This provides Git with the necessary token to access the private repository.
VolumeClaimTemplates
Argo workflows can define VolumeClaimTemplates. This is a list of claims that containers are allowed to reference. The workflow controller will create the claims at the beginning of the workflow and delete the claims upon completing the workflow. If you need multiple steps to access your source without having to mount it each time, you can use a VolumeClaimTemplate. We define our claim in the Workflow.spec like this:
volumeClaimTemplates:
- metadata:
name: workdir
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
Our Argo step to clone the repo needs to add the `volumeMount` like this:
templates:
- name: git-clone
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "git-creds"
vault.hashicorp.com/secret-volume-path: "/home"
vault.hashicorp.com/agent-inject-secret-token: "secret/git-creds"
vault.hashicorp.com/agent-inject-template-token: |
{{- with secret "secret/git-creds" -}}
{{ .Data.data.token }}
{{- end }}
container:
image: alpine/git
command: [sh, -c]
args: ["git clone -b {{workflow.parameters.git-repo-revision}} https://`cat /home/token`@{{workflow.parameters.git-repo-url}} ."]
workingDir: "/gen-source{{workflow.parameters.git-repo-path}}"
volumeMounts:
- name: workdir
mountPath: /gen-source
Any other subsequent step in need of the source code would include the same `volumeMounts` section and have access from the pod to the source code at `/gen-source/src`.
Vault Secret as Output Parameter
We can use the same Vault secret injection as an output parameter concept as an input parameter to another step. What if, in a later step, we wanted to push a change to our Git repository? If we use the first example where we created the token file, we could change the `container.args` file as follows:
container:
args: ["cat /home/token"]
Now you can reference the output of this step as `task.[TASK_NAME].outputs.result`.
Helm
Since the Argo workflow is just a CustomResource, we can easily create a Helm chart to define, install and upgrade our workflows. Argo uses Helm-like templating for its parameters. Workflow parameters can be defined within your steps, such as the following:
spec:
arguments:
parameters:
- name: best-football-team
value: Steelers
- name: favorite-drink
value: whiskey
When defining your step templates, you could set envs based on these workflow parameters like this:
- name: my-step
container:
env:
- name: FOOTBALL_TEAM
value: "{{workflow.parameters.best-football-team}}"
- name: DRINK
value: "{{workflow.parameters.favorite-drink}}"
If we want to turn this into a Helm chart, we would do the following:
spec:
arguments:
parameters:
- name: best-football-team
value: "{{ tpl (required "value 'bestFootballTeam' required" .Values.bestFootballTeam }}"
- name: favorite-drink
value: "{{ tpl (required "value 'favoriteDrink' required" .Values.favoriteDrink }}"
templates:
- name: my-step
container:
env:
- name: FOOTBALL_TEAM
value: '{{ printf "{{workflow.parameters.best-football-team}}" }}'
- name: DRINK
value: '{{ printf "{{workflow.parameters.favorite-drink}}" }}'
Notice the use of the Helm string function printf. Since Argo utilizes the double curly bracket just like Helm as a template directive, we need to "escape" Argo's parameters. If we did not escape them, Helm would attempt to inject a value, resulting in an empty string instead of the intended Argo parameter. There are other ways to escape the double curly braces, but I find the printf function to be the cleanest solution.
Summary
Unfortunately, Argo does not have support for Vault. Fortunately, it's fairly easy to utilize Vault's Agent Sidecar Injector to inject secrets into your Argo workflow. Helm makes it really easy to parameterize your workflows for reuse. Just don't forget to escape any Argo parameters!
Complete Argo workflows and installation steps can be found in the argo-workflow-vault-integration repo.
저자 소개
유사한 검색 결과
Red Hat to acquire Chatterbox Labs: Frequently Asked Questions
Attestation vs. integrity in a zero-trust world
What Is Product Security? | Compiler
Technically Speaking | Security for the AI supply chain
채널별 검색
오토메이션
기술, 팀, 인프라를 위한 IT 자동화 최신 동향
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
오픈 하이브리드 클라우드
하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
가상화
온프레미스와 클라우드 환경에서 워크로드를 유연하게 운영하기 위한 엔터프라이즈 가상화의 미래