Using secrets in your change
This example describes how to use Kubernetes secrets in your change. After following this guide you should understand:
- how OpsChain's build secrets configuration can be used to securely pass secrets to your step runner image build
- how OpsChain's runner secrets configuration can be used to export environment variables in your step
- Kubernetes secrets are, by default, stored unencrypted in the Kubernetes cluster's underlying data store (etcd). See the good practices for Kubernetes secrets guide for information on how to encrypt them at rest and further restrict user access to them.
- This guide is for use by non-SaaS OpsChain customers only. Let us know if you're interested in using secrets in your SaaS instance.
Prerequisites
- A running OpsChain instance (see the installation guide for more information)
kubectl
access to the Kubernetes cluster- A working understanding of Kubernetes secrets
- A fork of the sample repo to follow this example in. See the developer getting started guide for more information.
Example setup
Create a project & environments
Start by creating a project and two environments to use for this example:
opschain project create --code secret --name 'Secret example' -y
export opschain_projectCode=secret # the rest of this guide assumes this environment variable is set
opschain environment create --code dev --name Development -y
opschain environment create --code prod --name Production -y
Add a project Git remote
Add your fork of the OpsChain getting started guide repository as the Git remote for the secret
project:
opschain project add-git-remote --name origin \
--user '{username}' \
--password '{personal access token}' \
--url 'https://github.com/{username}/opschain-getting-started.git' \
--ssh-key-file '' \
--confirm
You can use SSH authentication if it's easier for you.
Create a branch for the example
To isolate your changes for this example, create a new branch in your fork of the OpsChain getting started repository:
cd /path/to/fork/of/opschain-getting-started
git checkout -b secret-example origin/developer-guide
Create a project Dockerfile
Use the OpsChain CLI to create a Dockerfile for the project:
OPSCHAIN_LICENCE=/path/to/opschain.lic opschain dev create-dockerfile
In order to see the effect your changes are making to the build environment, edit the .opschain/Dockerfile
so the image build will display the current value of all environment variables. We suggest adding it above the RUN
for opschain-exec bundle install
:
RUN --mount=type=secret,required=true,id=env_context_json,uid=10001,gid=10001,target=/opt/opschain/.opschain/step_context.json \
opschain-exec env
In order to see the effect your changes are making to the step runner environment, edit the actions.rb
and add an action to display the current value of all environment variables:
action :show_environment do
sh 'env'
end
Add the updated files to your branch and push to GitHub:
git add .opschain/Dockerfile actions.rb
git commit -m 'Add secret demo.'
git push --set-upstream origin secret-example
Verify your setup
Verify everything is configured properly by running the new show_environment
action:
opschain change create --environment-code dev --action show_environment --git-remote-name origin --git-rev secret-example --follow-logs --confirm
Watch the logs for the RUN
command you modified and verify the environment variables available during the build are being displayed in the logs, for example:
#13 [stage-0 5/6] RUN --mount=type=secret,required=true,id=env_context_json,uid=10001,gid=10001,target=/opt/opschain/.opschain/step_context.json opschain-exec env & opschain-exec bundle install
#13 1.068 LANG=C.UTF-8
#13 1.068 HISTCONTROL=ignoredups
#13 1.068 HOSTNAME=
#13 1.068 OLDPWD=/usr/local/bin
#13 1.068 GIT_REV=secret-example
#13 1.068 BUNDLE_JOBS=20
#13 1.068 GIT_SHA=d4e74b76bf82f3529ab237e430f997ecfe3e4711
#13 1.068 USER=opschain
#13 1.068 RBENV_SHELL=bash
#13 1.068 PWD=/opt/opschain
#13 1.068 HOME=/opt/opschain
#13 1.068 RBENV_DIR=/usr/local/bin
...
Continue watching the logs to see the show_environment
action outputting the runtime environment variables:
...
===> Starting step action "show_environment" (dry_run: false) at 2022-12-20T12:20:21.905+11:00
env
OPSCHAIN_BUILD_SERVICE_PORT_50000_TCP_ADDR=10.43.197.162
OPSCHAIN_DB_SERVICE_PORT_DB=5432
OPSCHAIN_LDAP_SERVICE_PORT=389
...
Default build secrets
The key value pairs configured in the opschain-build-env
Kubernetes secret are made available as environment variables to all step runner image builds by default. To see this in action, let's add a GitHub personal access token into the opschain-build-env
secret. This will allow all the projects created in our OpsChain instance to connect to GitHub (and, for example, download a Gem from a private repository).
Edit the
opschain-build-env
secret:kubectl edit secret -n opschain opschain-build-env # this assumes you are using the default `opschain` Kubernetes namespace for OpsChain
Add the
BUNDLE_GITHUB__COM
key value pair asstringData
into the secret:apiVersion: v1
kind: Secret
...
stringData:
BUNDLE_GITHUB__COM: ghp_zWISaqpAk1mwCrTZl9SKsNVFDekp4f2wgfvx==tipAs we are not actually accessing a secure Gem in this example, there is no need to generate a new access token - you can use the dummy access token in the example yaml above.
Re-run the
show_environment
action and verify:- The
BUNDLE_GITHUB__COM
environment variable is available to the image build - The
BUNDLE_GITHUB__COM
environment variable is not set during the step execution - OpsChain has obfuscated the value in the logs, so it is not visible to anyone with access to the logs:
opschain change create --environment-code dev --action show_environment --git-remote-name origin --git-rev secret-example --follow-logs --confirm
#13 [stage-0 5/6] RUN --mount=type=secret,required=true,id=env_context_json,uid=10001,gid=10001,target=/opt/opschain/.opschain/step_context.json opschain-exec env
...
#13 1.068 BUNDLE_GITHUB__COM=****************************************
...- The
Default runner secrets
Follow the same process as the default build secrets, but modify the opschain-runner-env
Kubernetes secret instead.
Re-run the show_environment
action and verify that the obfuscated BUNDLE_GITHUB__COM
environment variable is now shown during the step execution.
...
===> Starting step action "show_environment" (dry_run: false) at 2022-12-20T12:20:21.905+11:00
env
OPSCHAIN_BUILD_SERVICE_PORT_50000_TCP_ADDR=10.43.197.162
OPSCHAIN_DB_SERVICE_PORT_DB=5432
OPSCHAIN_LDAP_SERVICE_PORT=389
...
BUNDLE_GITHUB__COM=****************************************
...
Project & environment secrets
The secrets used by a change run in a particular project environment can be configured specifically - rather than using the default opschain-build-env
and opschain-runner-env
secrets.
To see this in action, let's start by adding some project level credentials to our secret
project:
Project build secrets
Create a Kubernetes secret containing the project level secrets:
$ cat << EOF > custom-project-secrets.yaml
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: custom-project-secrets
namespace: opschain
stringData:
CLOUD_SECRET_KEY: cloud-secret-key
ARTIFACTORY_USER: project-username
ARTIFACTORY_PASSWORD: project-password
EOF
$ kubectl apply -f custom-project-secrets.yamltipAlter the namespace if you are using a different namespace for your OpsChain installation.
Update the
secret
project'sopschain
properties to include the Kubernetes secret:opschain project edit-properties -p secret
{
"opschain": {
"env:build_secrets": ["custom-project-secrets"],
"env:runner_secrets": ["custom-project-secrets"]
}
}Re-run the
hello_world
action and verify:- the
BUNDLE_GITHUB__COM
environment variable from the default secret is no longer available to the step - the
CLOUD_SECRET_KEY
,ARTIFACTORY_USER
andARTIFACTORY_PASSWORD
environment variables from thecustom-project-secrets
secret are available at build time - the
CLOUD_SECRET_KEY
,ARTIFACTORY_USER
andARTIFACTORY_PASSWORD
environment variables from thecustom-project-secrets
secret are available in the runner - the secret values are obfuscated
opschain change create --environment-code dev --action show_environment --git-remote-name origin --git-rev secret-example --follow-logs --confirm
- the
Environment secrets
Just like properties, OpsChain's secret model allows you to override project level secrets at the environment level. Lets add some developer credentials to our dev
environment, so the production credentials are not visible to the development team.
Create a Kubernetes secret containing specific credentials for the development team:
$ cat << EOF > dev-secrets.yaml
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: dev-secrets
namespace: opschain
stringData:
ARTIFACTORY_USER: dev-username
ARTIFACTORY_PASSWORD: dev-password
EOF
$ kubectl apply -f dev-secrets.yamltipAlter the namespace if you are using a different namespace for your OpsChain installation.
Update your dev environment
opschain
properties to use the newdev-secrets
secret:opschain environment edit-properties -p secret -e dev
{
"opschain": {
"env:build_secrets": ["dev-secrets"],
"env:runner_secrets": ["dev-secrets"]
}
}Re-run the
show_environment
action and note the obfuscatedARTIFACTORY
credentials differ to the previous run as they now reflect thedev-secrets
values - this can only been seen via the change of length due to the obfuscation:opschain change create --environment-code dev --action show_environment --git-remote-name origin --git-rev secret-example --follow-logs --confirm
Including the default secrets
As shown above, adding env:build_secrets
or env:runner_secrets
to your project or environment opschain
properties disables the default secrets from being supplied to the relevant part of the step. If your project or environment requires the default secrets, simply add the relevant secret to your project configuration:
For example, edit the project properties and add the
opschain-build-env
secret to theenv:build_secrets
:opschain project edit-properties -p secret
{
"opschain": {
"env:build_secrets": ["opschain-build-env", "custom-project-secrets"]
}
}Run the
show_environment
action and note theBUNDLE_GITHUB__COM
, projectCLOUD_SECRET_KEY
and environmentARTIFACTORY_USER
andARTIFACTORY_PASSWORD
are all available to the build:opschain change create --environment-code dev --action show_environment--git-remote-name origin --git-rev secret-example --follow-logs --confirm
- the
env:build_secrets
are only used when building the image. The secrets are not available to OpsChain actions - the
env:runner_secrets
are only used when running the action. The secrets are not available when building the image - when a property and a secret both define the same environment variable, the secret value will be used