amacrobert
amacrobert

Reputation: 3149

How do I use GitHub Actions envrionment variables in a job called with workflow_call

I have 2 workflows: CI/CD and Deploy.

Deploy can be triggered manually (with workflow_dispatch) or by CI/CD (with workflow_call). It uses an environment named "dev" that contains 2 secrets: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

The Deploy workflow is successful when called manually. However, when it's called from CI/CD, it fails with

Error: Credentials could not be loaded, please check your action inputs: Could not load credentials from any providers

Here are the relevant parts of my workflows:

.github/workflows/ci-cd.yaml

name: CI/CD
on:
  pull_request:
    branches: [ main ]

jobs:
  ci:
    name: CI Checks
    runs-on: ubuntu-latest

    steps:
      # ... (run static analysis and tests)

  deploy-to-qa:
    name: Deploy to staging
    needs: [ ci ]
    uses: org/repo/.github/workflows/deploy.yaml@main
    with:
      AWS_REGION: us-east-1

.github/workflows/deploy.yaml

name: Deploy
on:
  workflow_call:
    inputs:
      AWS_REGION: { required: true, type: string }
  workflow_dispatch:
    inputs:
      AWS_REGION:
        required: true
        default: us-east-1

jobs:
  build-and-deploy:
    name: Deploy
    runs-on: ubuntu-latest
    environment: dev
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      ###############
      # THIS STEP FAILS when run with workflow_call (but succeeds with workflow_dispatch)
      ###############
      - name: Configure aws creds
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ inputs.AWS_REGION }}

The error: aws-actions/configure-aws-credentials@v1
error: Credential could not be loaded

Upvotes: 4

Views: 1985

Answers (3)

EL96NG8C NG
EL96NG8C NG

Reputation: 167

to use aws-actions/configure-aws-credentials in a reusable workflow you explicitly pass the required credentials:

# reusable run_tests.yml

name: Run Tests
on:
  workflow_call: # allows calling this workflow from another workflow
    secrets:
      AWS_ACCESS_KEY_ID: { required: true }
      AWS_SECRET_ACCESS_KEY: { required: true }

jobs:
  tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: eu-west-1
      # - ... rest of the steps...
# your caller workflow (main workflow)

jobs:
  tests:
    uses: ./.github/workflows/run_tests.yml
    secrets:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  build-and-push:
  ...

took me few hours to figure this out...

Upvotes: 0

GuiFalourd
GuiFalourd

Reputation: 22970

The workflow_call needs secrets to be sent separately:

A map of the secrets that can be used in the called workflow.

Example

on:
  workflow_call:
    secrets:
      access-token:
        description: 'A token passed from the caller workflow'
        required: false

jobs:

  pass-secret-to-action:
    runs-on: ubuntu-latest
    steps:
    # passing the secret to an action
      - name: Pass the received secret to an action
        uses: ./.github/actions/my-action
        with:
          token: ${{ secrets.access-token }}

  # passing the secret to a nested reusable workflow
  pass-secret-to-workflow:
    uses: ./.github/workflows/my-workflow
    secrets:
       token: ${{ secrets.access-token }}

Reference


Moreover, according to this blog post, you can inherit secrets now:

GitHub Actions simplifies using secrets with reusable workflows with the secrets: inherit keyword.

Previously when passing secrets to a reusable workflow, you had to pass each secret as a separate argument. Now you can simply pass the secrets: inherit to the reusable workflow and the secrets will be inherited from the calling workflow.

Upvotes: 2

Matteo
Matteo

Reputation: 39390

You should define that as input params in the workflow_call section and pass them in the caller workflow. Like:

on:
  workflow_call:
    inputs:
      AWS_REGION: { required: true, type: string }
      AWS_ACCESS_KEY_ID: { required: true, type: string }
      AWS_SECRET_ACCESS_KEY: { required: true, type: string }

and use it like:

    with:
      aws-access-key-id: ${{ inputs.AWS_ACCESS_KEY_ID }}
      aws-secret-access-key: ${{ inputs.AWS_SECRET_ACCESS_KEY }}
      aws-region: ${{ inputs.AWS_REGION }}

In this way you could lost the ability to call with a workflow_dispatch. In order to support that also, you could try this approach:

    with:
      aws-access-key-id: ${{ inputs.AWS_ACCESS_KEY_ID ||  secrets.AWS_ACCESS_KEY_ID }}
      aws-secret-access-key: ${{ inputs.AWS_SECRET_ACCESS_KEY ||  secrets.AWS_SECRET_ACCESS_KEY }}
      aws-region: ${{ inputs.AWS_REGION }}

Not tested, may require an intermediary step to resolve this part

Upvotes: 2

Related Questions