A small learning project for invoking an AWS Lambda directly from GitHub Actions using OIDC.
A dummy Lambda echoes its JSON input with an ok: true result. Terraform manages the function, its execution role, and a CloudWatch log group with seven-day retention. No triggers are configured.
The existing github-ci-role receives an inline policy granting lambda:InvokeFunction on this function's exact ARN. Terraform looks up the role without managing its trust policy or other permissions.
Example response for the payload {"hello":"github"}:
{ "ok": true, "payload": { "hello": "github" } }Configure AWS CLI credentials and set allowed_account_ids in terraform/main.tf to the target account ID. The GitHub OIDC role must already exist; its name is configured in terraform/github.tf. Initialize, validate, and preview the infrastructure:
terraform -chdir=terraform init
terraform -chdir=terraform fmt -check
terraform -chdir=terraform validate
terraform -chdir=terraform planDeploy:
terraform -chdir=terraform applyInvoke the function using an AWS identity with lambda:InvokeFunction permission:
aws lambda invoke \
--region eu-north-1 \
--function-name "$(terraform -chdir=terraform output -raw function_name)" \
--invocation-type RequestResponse \
--cli-binary-format raw-in-base64-out \
--payload '{"hello":"github"}' \
/tmp/lambda-oidc-invoke-response.json
cat /tmp/lambda-oidc-invoke-response.jsonSuccessful execution returns StatusCode: 200, no FunctionError, and the JSON response shown above. A successful API request alone does not indicate that the handler succeeded.
For GitHub Actions, set the repository secret AWS_ROLE_ARN to the existing GitHub OIDC role ARN under Settings → Secrets and variables → Actions → Secrets. The role's trust policy must allow this repository's OIDC subject.
The workflow runs on pushes to main and can also be started under Actions → Invoke dummy Lambda → Run workflow. It authenticates through OIDC, invokes the Lambda synchronously, and checks both the invocation metadata and response. No AWS access keys are required.
The manual should_fail checkbox controls the payload's shouldFail field:
| Payload | Lambda behavior | Workflow result |
|---|---|---|
{"shouldFail": false} |
Returns ok: true and the payload |
Pass |
{"shouldFail": true} |
Throws an error | Fail |
Push runs use shouldFail: false. To exercise both paths, run the workflow once with the checkbox unchecked and once checked. A Lambda handler error can still produce invocation metadata with StatusCode: 200; the workflow checks FunctionError and exits with a nonzero status when it is present.
Run the handler tests locally:
node --test lambda/index.test.mjs