Bird
Raised Fist0
Terraformcloud~3 mins

Why OIDC authentication for CI/CD in Terraform? - Purpose & Use Cases

Choose your learning style10 modes available
The Big Idea

Discover how to ditch secret keys and make your CI/CD pipeline both safer and easier!

The Scenario

Imagine you have a CI/CD pipeline that needs to access cloud resources securely. Without automation, you manually create and manage long-lived credentials or keys for each pipeline run.

The Problem

This manual approach is slow and risky. Keys can be leaked or forgotten to rotate, causing security holes. It's also a hassle to update credentials every time permissions change.

The Solution

OIDC authentication lets your CI/CD pipeline prove its identity dynamically using short-lived tokens. This removes the need for stored secrets and automates secure access to cloud resources.

Before vs After
✗ Before
aws_access_key = "OLD_KEY"
aws_secret_key = "OLD_SECRET"
✓ After
provider "aws" {
  region = "us-east-1"
}
What It Enables

It enables secure, automatic, and scalable access to cloud resources without managing static secrets.

Real Life Example

A developer pushes code to GitHub. The GitHub Actions workflow uses OIDC to get a temporary token and deploys the app to AWS without storing any AWS keys in the repo.

Key Takeaways

Manual credential management is slow and risky.

OIDC provides short-lived, automatic authentication for CI/CD.

This improves security and simplifies pipeline setup.

Practice

(1/5)
1. What is the main benefit of using OIDC authentication in CI/CD pipelines with Terraform?
easy
A. It disables all access restrictions for faster builds.
B. It automatically deploys code without any manual approval.
C. It replaces Terraform with a different infrastructure tool.
D. It allows secure authentication without storing passwords in the pipeline.

Solution

  1. Step 1: Understand OIDC purpose in CI/CD

    OIDC provides a secure way for pipelines to prove identity without passwords.
  2. Step 2: Connect to Terraform usage

    Terraform can create roles that trust OIDC tokens, avoiding password storage.
  3. Final Answer:

    It allows secure authentication without storing passwords in the pipeline. -> Option D
  4. Quick Check:

    OIDC = passwordless secure authentication [OK]
Hint: OIDC means no passwords needed in CI/CD [OK]
Common Mistakes:
  • Thinking OIDC automates deployment without approval
  • Confusing OIDC with replacing Terraform
  • Assuming OIDC disables access controls
2. Which Terraform resource block correctly defines an IAM role trusting GitHub Actions OIDC provider?
easy
A. resource "aws_iam_role" "github_oidc_role" { assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [{ Effect = "Allow", Principal = { Federated = "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com" }, Action = "sts:AssumeRoleWithWebIdentity" }] }) }
B. resource "aws_iam_role" "github_oidc_role" { assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [{ Effect = "Allow", Principal = { Service = "github.com" }, Action = "sts:AssumeRole" }] }) }
C. resource "aws_iam_role" "github_oidc_role" { assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [{ Effect = "Allow", Principal = { AWS = "arn:aws:iam::123456789012:root" }, Action = "sts:AssumeRoleWithWebIdentity" }] }) }
D. resource "aws_iam_role" "github_oidc_role" { assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [{ Effect = "Allow", Principal = { Federated = "arn:aws:iam::123456789012:oidc-provider/github.com" }, Action = "sts:AssumeRoleWithWebIdentity" }] }) }

Solution

  1. Step 1: Identify correct OIDC provider ARN format

    The OIDC provider ARN for GitHub Actions uses 'token.actions.githubusercontent.com'.
  2. Step 2: Check assume_role_policy structure

    The policy must allow 'sts:AssumeRoleWithWebIdentity' with Principal as Federated and correct ARN.
  3. Final Answer:

    The resource block with Federated principal using 'token.actions.githubusercontent.com' and 'sts:AssumeRoleWithWebIdentity' action. -> Option A
  4. Quick Check:

    Correct OIDC ARN + sts:AssumeRoleWithWebIdentity = resource "aws_iam_role" "github_oidc_role" { assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [{ Effect = "Allow", Principal = { Federated = "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com" }, Action = "sts:AssumeRoleWithWebIdentity" }] }) } [OK]
Hint: OIDC provider ARN uses token.actions.githubusercontent.com [OK]
Common Mistakes:
  • Using Service principal instead of Federated
  • Wrong OIDC provider ARN format
  • Using sts:AssumeRole instead of sts:AssumeRoleWithWebIdentity
3. Given this Terraform snippet for an IAM role trust policy, what is the effect of the condition block?
condition = {
  StringEquals = {
    "token.actions.githubusercontent.com:sub" = "repo:myorg/myrepo:ref:refs/heads/main"
  }
}
medium
A. Allows any GitHub repo to assume the role.
B. Restricts role assumption to the main branch of myorg/myrepo only.
C. Blocks all role assumptions from GitHub Actions.
D. Allows only forks of myorg/myrepo to assume the role.

Solution

  1. Step 1: Understand the condition key

    The condition uses 'token.actions.githubusercontent.com:sub' to specify the GitHub repo and branch.
  2. Step 2: Interpret the value

    The value 'repo:myorg/myrepo:ref:refs/heads/main' restricts access to the main branch of that repo only.
  3. Final Answer:

    Restricts role assumption to the main branch of myorg/myrepo only. -> Option B
  4. Quick Check:

    Condition limits to specific repo and branch = Restricts role assumption to the main branch of myorg/myrepo only. [OK]
Hint: Condition with repo and ref limits branch access [OK]
Common Mistakes:
  • Ignoring the branch restriction in condition
  • Assuming condition allows all repos
  • Confusing forks with original repo access
4. You wrote this Terraform assume_role_policy but your CI/CD pipeline fails to authenticate:
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/github.com" },
    "Action": "sts:AssumeRoleWithWebIdentity"
  }]
}
What is the most likely error?
medium
A. The Principal should use 'Service' instead of 'Federated'.
B. The Action should be 'sts:AssumeRole' instead of 'sts:AssumeRoleWithWebIdentity'.
C. The OIDC provider ARN is incorrect; it should be 'token.actions.githubusercontent.com'.
D. The Version date is invalid and must be updated.

Solution

  1. Step 1: Check the OIDC provider ARN

    The ARN 'arn:aws:iam::123456789012:oidc-provider/github.com' is incorrect for GitHub Actions.
  2. Step 2: Identify correct ARN for GitHub Actions

    The correct ARN uses 'token.actions.githubusercontent.com' as the OIDC provider host.
  3. Final Answer:

    The OIDC provider ARN is incorrect; it should be 'token.actions.githubusercontent.com'. -> Option C
  4. Quick Check:

    Wrong OIDC ARN causes auth failure = The OIDC provider ARN is incorrect; it should be 'token.actions.githubusercontent.com'. [OK]
Hint: Check OIDC ARN spelling carefully for GitHub Actions [OK]
Common Mistakes:
  • Using 'sts:AssumeRole' instead of 'sts:AssumeRoleWithWebIdentity'
  • Confusing Federated with Service principal
  • Ignoring ARN format for OIDC provider
5. You want to create a Terraform IAM role for GitHub Actions that only allows workflows from the 'release' branch of 'myorg/myrepo' to assume it. Which condition block correctly enforces this restriction?
hard
A. { "StringEquals": { "token.actions.githubusercontent.com:sub": "repo:myorg/myrepo:ref:refs/heads/release" } }
B. { "StringLike": { "token.actions.githubusercontent.com:sub": "repo:myorg/myrepo:ref:refs/heads/*" } }
C. { "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" } }
D. { "StringNotEquals": { "token.actions.githubusercontent.com:sub": "repo:myorg/myrepo:ref:refs/heads/main" } }

Solution

  1. Step 1: Understand the condition key and value

    To restrict to the 'release' branch, the condition must match 'repo:myorg/myrepo:ref:refs/heads/release'.
  2. Step 2: Choose correct operator

    'StringEquals' ensures exact match, so only 'release' branch is allowed.
  3. Final Answer:

    The condition block with StringEquals matching 'repo:myorg/myrepo:ref:refs/heads/release'. -> Option A
  4. Quick Check:

    Exact branch match uses StringEquals with correct ref [OK]
Hint: Use StringEquals with exact repo and branch ref [OK]
Common Mistakes:
  • Using StringLike with wildcard allowing all branches
  • Checking audience (aud) instead of subject (sub)
  • Using StringNotEquals which excludes main but allows others
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard