Terraform Backend
Using a Terraform Backend
terraform {
backend "s3" {
bucket = "bvc-terraform-state"
key = "live/main.tfstate"
region = "ca-central-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
required_providers {
aws = {
version = ">= 4.0.0"
source = "hashicorp/aws"
}
}
}
Create IAM Role for GitHub Actions
main.tf
# Create an IAM OIDC identity provider that trusts GitHub
resource "aws_iam_openid_connect_provider" "github_actions" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = [
data.tls_certificate.github.certificates[0].sha1_fingerprint
]
}
# Fetch GitHub's OIDC thumbprint
data "tls_certificate" "github" {
url = "https://token.actions.githubusercontent.com"
}
# Create role for the action
data "aws_iam_policy_document" "assume_role" {
statement {
actions = ["sts:AssumeRoleWithWebIdentity"]
effect = "Allow"
principals {
identifiers = [aws_iam_openid_connect_provider.github_actions.arn]
type = "Federated"
}
condition {
test = "StringLike"
variable = "token.actions.githubusercontent.com:sub"
# The repos and branches defined in var.allowed_repos_branches
# will be able to assume this IAM role
values = [
"repo:masoudkarimif/*:*"
]
}
}
}
# Assign policy to the role
resource "aws_iam_role" "github_actions_role" {
name_prefix = var.role_name_prefix
assume_role_policy = data.aws_iam_policy_document.assume_role.json
}
resource "aws_iam_role_policy" "this" {
role = aws_iam_role.github_actions_role.name
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:Get*"
],
"Resource": "arn:aws:s3:::${var.devops_bucket_name}/*",
"Effect": "Allow"
},
{
"Action": [
"lambda:UpdateFunctionCode"
],
"Resource": "*",
"Effect": "Allow"
}
]
}
POLICY
}
data "aws_iam_policy" "readonlyaccess" {
arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
resource "aws_iam_role_policy_attachment" "attachment" {
role = aws_iam_role.github_actions_role.name
policy_arn = data.aws_iam_policy.readonlyaccess.arn
}
variables.tf
variable "role_name_prefix" {
type = string
}
variable "devops_bucket_name" {
type = string
}
outputs.tf
output "role_name" {
value = aws_iam_role.github_actions_role.name
}
output "role_arn" {
value = aws_iam_role.github_actions_role.arn
}
Using Different Roles for Different Environments
In GitHub workflow:
# other stuff ...
name: deploy
# ...
- name: Configuration for master branch
if: ${{ github.ref == 'refs/heads/master' }}
run: |
echo "ROLE_ARN=${{ secrets.PROD_DEVOPS_ROLE }}" >> $GITHUB_ENV
echo "DEVOPS_BUCKET=PROD-BUCKET" >> $GITHUB_ENV
echo "ENV=PROD" >> $GITHUB_ENV
- name: Configuration for stage branch
if: ${{ github.ref == 'refs/heads/stage' }}
run: |
echo "ROLE_ARN=${{ secrets.STAGE_DEVOPS_ROLE }}" >> $GITHUB_ENV
echo "DEVOPS_BUCKET=STAGE-BUCKET" >> $GITHUB_ENV
echo "ENV=STAGE" >> $GITHUB_ENV
- name: AWS
uses: aws-actions/configure-aws-credentials@master
with:
role-to-assume: ${{ env.ROLE_ARN }}
role-session-name: samplerolesession
aws-region: us-east-1
# other stuff ...