Deploy Terraform Code using GitHub Actions with OpenID Connect (OIDC) identity providers (AWS Cloud)
Aslam Chandio
Cloud Engineer || 3x GCP Certified || 6x Azure Certified || 1x AWS Certified || 1x VMware Certified || Docker & Kubernetes|| Terraform || Linux || MCSA Certified ||
Overview:
OpenID Connect (OIDC) allows your GitHub Actions workflows to access resources in Amazon Web Services (AWS), without needing to store the AWS credentials as long-lived GitHub secrets.
This guide explains how to configure AWS to trust GitHub's OIDC as a federated identity, and includes a workflow example for the aws-actions/configure-aws-credentials that uses tokens to authenticate to AWS and access resources.
Prerequisites:
Step 1 — Create a repo on Github
Step 2 — Create OIDC Provider & Role in AWS Account
Create a file cf-basic.yml (Cloud formation File)
Name of Github user : "aslamchandio"
GitHub Repo name: "aws-oidc-terraform-github"
OIDC Provider: token.actions.githubusercontent.com
Role: github-actions-role
S3 Bucket: aslam-aws-terraform-github (Versioning enable)
DynamoDB Table: aslam-aws-terraform-github
Note: (S3 Bucket & DynamoDB Table for terraform remote state & locking purpose)
Parameters:
GitHubOrg:
Description: Name of GitHub organization/user (case sensitive)
Default: "aslamchandio"
Type: String
RepositoryName:
Description: Name of GitHub repository (case sensitive)
Default: "aws-oidc-terraform-github"
Type: String
OIDCProviderArn:
Description: Arn for the GitHub OIDC Provider.
Default: ""
Type: String
OIDCAudience:
Description: Audience supplied to configure-aws-credentials.
Default: "sts.amazonaws.com"
Type: String
Conditions:
CreateOIDCProvider: !Equals [!Ref OIDCProviderArn, ""]
Resources:
Role:
Type: AWS::IAM::Role
Properties:
RoleName: github-actions-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Action: sts:AssumeRoleWithWebIdentity
Principal:
Federated: !If
- CreateOIDCProvider
- !Ref GithubOidc
- !Ref OIDCProviderArn
Condition:
StringEquals:
token.actions.githubusercontent.com:aud: !Ref OIDCAudience
StringLike:
token.actions.githubusercontent.com:sub: !Sub repo:${GitHubOrg}/${RepositoryName}:*
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess
GithubOidc:
Type: AWS::IAM::OIDCProvider
Condition: CreateOIDCProvider
Properties:
Url: https://token.actions.githubusercontent.com
ClientIdList:
- sts.amazonaws.com
ThumbprintList:
- 6938fd4d98bab03faadb97b34396831e3780aea1
#- 1c58a3a8518e8759bf075b76b750d4f2df264fcd
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: aslam-aws-terraform-github
VersioningConfiguration:
Status: Enabled
DynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: aslam-aws-terraform-github
AttributeDefinitions:
- AttributeName: LockID
AttributeType: S
KeySchema:
- AttributeName: LockID
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
Outputs:
Role:
Value: !GetAtt Role.Arn
aws cloudformation create-stack \
--stack-name cf-basic \
--template-body file://cf-base.yml \
--capabilities "CAPABILITY_IAM" "CAPABILITY_NAMED_IAM"
Update provider.tf file
Step 3 — Clone repo from Github on your local machine
Step 4 — Create Folders in local Repo in Hierarchical way
1- Under aws-oidc-terraform-github repo create folder .github
2- under .github folder create workflows folder
3- under workflows folder create Github action files.
Step 5 — Github Actions Files
vpc-ci-dev-create.yml (For Creating AWS Resources)
Name: vpc-ci-dev-create
Branch: GitHub Action Trigger always run from Main branch
Paths: only changes done from aws-eks-vpc-production
AWS Account-Number: 123456789123 (Yours Account Number)
Run Env: Latest Ubuntu with terraform install
name: vpc-ci-dev-create
on:
push:
branches:
- main
paths:
- "aws-eks-vpc-production/*"
env:
# TF_LOG: INFO
AWS_ACCOUNT_NUMBER: 123456789123
defaults:
run:
shell: bash
working-directory: ./aws-eks-vpc-production
permissions:
contents: read
jobs:
deploy-dev:
runs-on: ubuntu-latest
# These permissions are needed to interact with GitHub's OIDC Token endpoint. New
permissions:
id-token: write
contents: read
steps:
- name: "Checkout"
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-region: us-east-1
role-to-assume: arn:aws:iam::${{env.AWS_ACCOUNT_NUMBER}}:role/github-actions-role
role-session-name: Session-GitHubActions
- name: Setup Terraform with specified version on the runner
uses: hashicorp/setup-terraform@v2
# with:
# terraform_version: 1.4.6
- name: Terraform format
id: fmt
run: terraform fmt -check
- name: Terraform init
id: init
run: terraform init
- name: Terraform validate
id: validate
run: terraform validate
- name: Terraform plan
id: plan
run: terraform plan
continue-on-error: true
- name: Terraform Plan Status
if: steps.plan.outcome == 'failure'
run: exit 1
- name: Terraform Apply
run: terraform apply -auto-approve
vpc-ci-dev-destroy.yml (For Destroying AWS Resources)
name: vpc-ci-dev-destroy
on: workflow_dispatch
env:
TF_LOG: INFO
AWS_ACCOUNT_NUMBER: 123456789123
permissions:
contents: read
jobs:
destroy:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./aws-eks-vpc-production
# These permissions are needed to interact with GitHub's OIDC Token endpoint.
permissions:
id-token: write
contents: read
steps:
- name: "Checkout"
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-region: us-east-1
role-to-assume: arn:aws:iam::${{env.AWS_ACCOUNT_NUMBER}}:role/github-actions-role
role-session-name: Session-GitHubActions
- name: Setup Terraform with specified version on the runner
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.6.5
- name: Terraform init
id: init
run: terraform init
- name: Terraform Destroy
run: terraform destroy -auto-approve
Step 6 — Create .gitignore file in terraform main folder
.gitignore (Ignore .terraform & .terraform.local.hcl file if you already run terraform on local machine
.terraform/
.terraform.lock.hcl
Step 7 — Switched from main to feature branch
We don't want push our terraform code into main branch that's why first push code into feature branch then Merage into main branch
领英推荐
bellow commands used in above images
git checkout -b feature
git add .
git status
git commit -m "Adding Terraform and Github action Files"
git push -u origin feature
Step 8 — Check Terraform Code on GitHub
see github main branch is empty
Terraform Code in feature branch
Step 9 — Check Terraform Code on GitHub
copy terraform code from feature to main branch using compare & pull request
All Code copy into main branch
Step 10 — Check Terraform Code deploy on GitHub Actions
Step 10 — Check AWS Resources on Console
Check terraform.tfstate file in s3 bucket
Check DynamoDB Table
Step 11 — Destroy AWS Resource from Github Actions
using here vpc-ci-dev-destroy.yml
Links:
Senior System Reliability Engineer / Platform Engineer
1 年Found this article at the right time. It's just what the Dr. ordered.