GitHub Actions Certification
Reusable Workflows and Reporting
Step 3 Using Inputs in Reusable Workflow
In this guide, you’ll learn how to pass inputs into GitHub Actions reusable workflows to handle configuration values—such as MongoDB credentials—without relying on environment variables in the caller workflow.
Warning
Environment variables defined in a caller workflow do not propagate into a called reusable workflow. Attempting to pass sensitive data like database URIs via env:
will result in empty values.
For example, this command fails to set MONGO_URI
:
kubectl -n development create secret generic mongo-db-creds \
--from-literal=MONGO_URI= \
--from-literal=MONGO_USERNAME=superuser \
--from-literal=MONGO_PASSWORD=*** \
--save-config \
--dry-run=client \
-o yaml | kubectl apply -f -
This is a documented limitation of reusable workflows.
1. Define a Basic Reusable Workflow
Create a workflow—e.g. .github/workflows/reuse-deployment.yml
—that declares the required secrets
under workflow_call
. This allows callers to supply kubeconfig and database passwords securely:
name: Deployment - Reusable Workflow
on:
workflow_call:
secrets:
k8s-kubeconfig:
required: true
mongodb-password:
required: true
jobs:
reuse-deploy:
environment:
name: development
url: https://${{ steps.set-ingress-host-address.outputs.APP_INGRESS_HOST }}
outputs:
APP_INGRESS_URL: ${{ steps.set-ingress-host-address.outputs.APP_INGRESS_HOST }}
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Install kubectl CLI
uses: azure/setup-kubectl@v3
with:
version: '1.26.0'
- name: Set Kubeconfig file
uses: azure/k8s-set-context@v3
with:
method: kubeconfig
kubeconfig: ${{ secrets.k8s-kubeconfig }}
- name: Fetch Kubernetes Cluster Details
run: |
kubectl version --short
echo "-------------------------------------------"
kubectl get nodes
- name: Save Nginx Ingress Controller IP as an Output
id: set-ingress-host-address
run: |
IP=$(kubectl -n ingress-nginx get svc ingress-nginx-controller \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "APP_INGRESS_HOST=$IP" >> $GITHUB_OUTPUT
- name: Replace Tokens in Manifests
uses: cschijden/replace-tokens@v1
with:
tokenPrefix: __
tokenSuffix: __
files: ["kubernetes/development/*.yaml"]
env:
NAMESPACE: ${{ vars.NAMESPACE }}
REPLICAS: ${{ vars.REPLICAS }}
IMAGE: ${{ vars.DOCKERHUB_USERNAME }}/solar-system:${{ github.sha }}
INGRESS_IP: ${{ steps.set-ingress-host-address.outputs.APP_INGRESS_HOST }}
- name: Inspect Rendered Manifests
run: cat kubernetes/development/*.yaml
- name: Create MongoDB Secret
run: |
kubectl -n ${{ vars.NAMESPACE }} create secret generic mongo-db-creds \
--from-literal=MONGO_URI=${{ env.MONGO_URI }} \
--from-literal=MONGO_USERNAME=${{ vars.MONGO_USERNAME }} \
--from-literal=MONGO_PASSWORD=${{ secrets.mongodb-password }} \
--save-config
- name: Deploy to Development Environment
run: kubectl apply -f kubernetes/development
2. Store MongoDB URI as a Repository Variable
Go to Settings > Actions > Secrets and variables > Variables and add:
- Name:
MONGO_URI
- Value:
mongodb+srv://supercluster.d8jj.mongodb.net/superData
Now the workflow can reference env.MONGO_URI
without relying on the caller’s env:
block.
3. Add workflow_call
Inputs
Enhance your reusable workflow by defining typed inputs
for maximum flexibility:
name: Deployment - Reusable Workflow
on:
workflow_call:
inputs:
mongodb-uri:
description: MongoDB connection string
required: true
type: string
kubectl-version:
description: kubectl CLI version
required: false
default: v1.26.0
type: string
k8s-manifest-dir:
description: Path to Kubernetes manifests
required: true
default: kubernetes/
type: string
environment:
description: Deployment environment name
required: true
default: dev
type: string
secrets:
k8s-kubeconfig:
required: true
mongodb-password:
required: true
Inputs Reference Table
Input Name | Type | Required | Default | Description |
---|---|---|---|---|
mongodb-uri | string | Yes | — | MongoDB connection string |
kubectl-version | string | No | v1.26.0 | Version of kubectl to install |
k8s-manifest-dir | string | Yes | kubernetes/ | Directory containing manifests |
environment | string | Yes | dev | Name of the target environment |
Update steps to reference inputs
instead of hard-coded values:
jobs:
reuse-deploy:
environment:
name: ${{ inputs.environment }}
url: https://${{ steps.set-ingress-host-address.outputs.APP_INGRESS_HOST }}
runs-on: ubuntu-latest
steps:
# ...
- name: Install kubectl CLI
uses: azure/setup-kubectl@v3
with:
version: ${{ inputs.kubectl-version }}
# ...
- name: Replace Tokens in Manifests
uses: cschijden/replace-tokens@v1
with:
files: ["${{ inputs.k8s-manifest-dir }}*.yaml"]
env:
INGRESS_IP: ${{ steps.set-ingress-host-address.outputs.APP_INGRESS_HOST }}
# ...
- name: Create MongoDB Secret
run: |
kubectl -n ${{ vars.NAMESPACE }} create secret generic mongo-db-creds \
--from-literal=MONGO_URI=${{ inputs.mongodb-uri }} \
--from-literal=MONGO_USERNAME=${{ vars.MONGO_USERNAME }} \
--from-literal=MONGO_PASSWORD=${{ secrets.mongodb-password }} \
--save-config \
--dry-run=client -o yaml | kubectl apply -f -
# ...
- name: Deploy to ${{ inputs.environment }}
run: kubectl apply -f "${{ inputs.k8s-manifest-dir }}"
4. Call the Reusable Workflow with Inputs
In your caller workflow (e.g. .github/workflows/dev-deploy.yml
), pass inputs via with:
and secrets as before:
dev-deploy:
if: contains(github.ref, 'feature/')
needs: docker
uses: ./.github/workflows/reuse-deployment.yml
with:
mongodb-uri: ${{ vars.MONGO_URI }}
kubectl-version: v1.27.0 # optional override
environment: development
k8s-manifest-dir: kubernetes/development/
secrets:
k8s-kubeconfig: ${{ secrets.KUBECONFIG }}
mongodb-password: ${{ secrets.MONGO_PASSWORD }}
prod-deploy:
if: github.ref == 'refs/heads/main'
needs: docker
uses: ./.github/workflows/reuse-deployment.yml
with:
mongodb-uri: ${{ vars.MONGO_URI }}
environment: production
k8s-manifest-dir: kubernetes/production/
secrets:
k8s-kubeconfig: ${{ secrets.KUBECONFIG }}
mongodb-password: ${{ secrets.MONGO_PASSWORD }}
After pushing, the dev-deploy run shows the inputs and secrets correctly applied:
You’ll see:
mongodb-uri
sourced from the repository variable.kubectl-version
defaulting to v1.26.0 unless overridden.- The manifest directory and environment matching the
with:
values.
The MongoDB secret creation now succeeds:
kubectl -n development create secret generic mongo-db-creds \
--from-literal=MONGO_URI=mongodb+srv://supercluster.d8jj.mongodb.net/superData \
--from-literal=MONGO_USERNAME=superuser \
--from-literal=MONGO_PASSWORD=*** \
--save-config \
--dry-run=client \
-o yaml | kubectl apply -f -
Note
If you need outputs (like APP_INGRESS_URL
) in the caller workflow, use outputs
in the reusable workflow and capture them via the needs
context.
Links and References
- Reusable Workflows in GitHub Actions
- azure/setup-kubectl Action
- azure/k8s-set-context Action
- GitHub Actions Variables
- GitHub Actions Secrets
Watch Video
Watch video content