Skip to content

Commit

Permalink
feat: centralize iam role setup for github actions
Browse files Browse the repository at this point in the history
- Added a new Terraform project to centralize IAM role configurations for GitHub Actions.
- Migrated IAM role setup from ECR configuration into this project.
- Expanded permissions to allow GitHub Actions to update ECS services in both prod and dev.
  • Loading branch information
jboix committed Oct 28, 2024
1 parent d8d2610 commit 75d06fa
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 98 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ The project is split into four main Terraform configurations:
Monitoring infrastructure. **This applies to both dev and prod environments**. You can switch
between workspaces (as mentioned earlier) to deploy infrastructure in either the dev or prod
account.
- [21-continuous-delivery][cd]: This configuration contains the definition of the IAM roles that
allow access to GitHub Action for specific repositories and operations. **This applies to both
dev and prod environments**. You can switch between workspaces (as mentioned earlier) to deploy
infrastructure in either the dev or prod account.
### System Flow Overview
Expand Down Expand Up @@ -170,3 +174,4 @@ This project is licensed under the [MIT License](LICENSE).
[route-53]: /pillarbox-monitoring-terraform/10-pillarbox-monitoring-route-53
[ecr]: /pillarbox-monitoring-terraform/11-pillarbox-monitoring-ecr
[app]: /pillarbox-monitoring-terraform/20-pillarbox-monitoring-app
[cd]: /pillarbox-monitoring-terraform/21-continuous-delivery
88 changes: 0 additions & 88 deletions pillarbox-monitoring-terraform/11-pillarbox-monitoring-ecr/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -77,94 +77,6 @@ resource "aws_ecr_lifecycle_policy" "ecr_lifecycles" {
EOF
}

# -----------------------------------
# IAM Configuration for GitHub Actions
# -----------------------------------

## Set Up OIDC Provider

resource "aws_iam_openid_connect_provider" "github_actions" {
# Create an IAM OIDC provider for GitHub Actions
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = var.github_thumbprint_list
}

## Define IAM Policy Documents

### Assume Role Policy Document

data "aws_iam_policy_document" "gha_assume_policy" {
# Generate policy documents for assuming IAM roles via OIDC
for_each = var.ecr_repositories

statement {
effect = "Allow"
actions = ["sts:AssumeRoleWithWebIdentity"]
principals {
type = "Federated"
identifiers = [aws_iam_openid_connect_provider.github_actions.arn]
}
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:aud"
values = ["sts.amazonaws.com"]
}
condition {
test = "StringLike"
variable = "token.actions.githubusercontent.com:sub"
values = ["repo:${each.value}:*"]
}
}
}

### Permissions Policy Document

data "aws_iam_policy_document" "gha_policy" {
# Define permissions for GitHub Actions to interact with ECR
for_each = var.ecr_repositories

# Allow Docker login to ECR
statement {
sid = "AllowDockerLogin"
effect = "Allow"
actions = ["ecr:GetAuthorizationToken"]
resources = ["*"]
}

# Allow pushing and pulling images to/from ECR
statement {
sid = "AllowPushPull"
effect = "Allow"
actions = [
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage"
]
resources = [aws_ecr_repository.repositories[each.key].arn]
}
}

## Create IAM Roles for GitHub Actions

resource "aws_iam_role" "gha_role" {
# Create IAM roles for each ECR repository for GitHub Actions
for_each = var.ecr_repositories

name = "gh-actions-role-${each.key}"
assume_role_policy = data.aws_iam_policy_document.gha_assume_policy[each.key].json

# Attach inline policy for ECR permissions
inline_policy {
name = "GithubActionECRBuilds"
policy = data.aws_iam_policy_document.gha_policy[each.key].json
}
}

# -----------------------------------
# Cross-Account ECR Access Configuration
# -----------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
# See https://github.blog/changelog/2023-06-27-github-actions-update-on-oidc-integration-with-aws/
variable "github_thumbprint_list" {
type = list(string)
description = "Github Thumbprint list"
default = [
"6938fd4d98bab03faadb97b34396831e3780aea1",
"1c58a3a8518e8759bf075b76b750d4f2df264fcd"
]
}

variable "ecr_repositories" {
description = "Map of ECR repository names to their associated GitHub repository"
type = map(string)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions pillarbox-monitoring-terraform/21-continuous-delivery/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
locals {
ecs_cluster_name = "${var.application_name}-cluster"
is_prod = terraform.workspace == "prod"

default_tags = {
"srg-managed-by" = "terraform"
"srg-application" = var.application_name
"srg-owner" = "[email protected]"
"srg-businessowner" = "pillarbox"
"srg-environment" = terraform.workspace
}
}
158 changes: 158 additions & 0 deletions pillarbox-monitoring-terraform/21-continuous-delivery/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# -----------------------------------
# Terraform Configuration
# -----------------------------------

terraform {
# Backend configuration for storing the Terraform state in S3 with DynamoDB table for state locking
backend "s3" {
encrypt = true
bucket = "pillarbox-monitoring-tfstate"
key = "terraform/21-continuous-delivery/terraform.tfstate"
dynamodb_table = "pillarbox-monitoring-terraform-statelock"
profile = "prod"
}

# Specify required providers and their versions
required_providers {
aws = {
source = "hashicorp/aws"
version = "~>5.4.0"
}
}
}

# -----------------------------------
# AWS Provider Setup
# -----------------------------------

provider "aws" {
# Apply default tags to all AWS resources
default_tags {
tags = local.default_tags
}
}

# -----------------------------------
# AWS Data Sources
# -----------------------------------

# Get current AWS region
data "aws_region" "current" {}

# Get current AWS identity
data "aws_caller_identity" "current" {}

# -----------------------------------
# IAM Configuration for GitHub Actions
# -----------------------------------

## Set Up OIDC Provider

resource "aws_iam_openid_connect_provider" "github_actions" {
# Create an IAM OIDC provider for GitHub Actions
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = var.github_thumbprint_list
}

## Define IAM Policy Documents

### Assume Role Policy Document

data "aws_iam_policy_document" "gha_assume_policy" {
# Generate policy documents for assuming IAM roles via OIDC
for_each = var.service_mappings

statement {
effect = "Allow"
actions = ["sts:AssumeRoleWithWebIdentity"]
principals {
type = "Federated"
identifiers = [aws_iam_openid_connect_provider.github_actions.arn]
}
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:aud"
values = ["sts.amazonaws.com"]
}
condition {
test = "StringLike"
variable = "token.actions.githubusercontent.com:sub"
values = ["repo:${each.value.github_repo_name}:*"]
}
}
}

### Permissions Policy Document

data "aws_iam_policy_document" "gha_policy" {
# Define permissions for GitHub Actions to interact with ECR and ECS
for_each = var.service_mappings

# Allow Docker login to ECR
dynamic "statement" {
for_each = local.is_prod ? [1] : []

content {
sid = "AllowDockerLogin"
effect = "Allow"
actions = ["ecr:GetAuthorizationToken"]
resources = ["*"]
}
}

# Allow pushing and pulling images to/from ECR
dynamic "statement" {
for_each = local.is_prod ? [1] : []

content {
sid = "AllowPushPull"
effect = "Allow"
actions = [
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage"
]
resources = [
"arn:aws:ecr:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:repository/${each.value.ecr_image_name}"
]

}
}

# Allow updating ECS services
statement {
sid = "AllowUpdateService"
effect = "Allow"
actions = [
"ecs:UpdateService",
"ecs:DescribeServices"
]
resources = [
"arn:aws:ecs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:cluster/${local.ecs_cluster_name}",
"arn:aws:ecs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:service/${local.ecs_cluster_name}/${each.key}"
]
}
}

## Create IAM Roles for GitHub Actions

resource "aws_iam_role" "gha_role" {
# Create IAM roles for each service
for_each = var.service_mappings

name = "gh-actions-role-${each.key}"
assume_role_policy = data.aws_iam_policy_document.gha_assume_policy[each.key].json

# Attach inline policy for ECR and ECS permissions
inline_policy {
name = "GithubActionPermissions"
policy = data.aws_iam_policy_document.gha_policy[each.key].json
}
}


34 changes: 34 additions & 0 deletions pillarbox-monitoring-terraform/21-continuous-delivery/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
variable "application_name" {
description = "The name of the application"
type = string
default = "pillarbox-monitoring"
}

# See https://github.blog/changelog/2023-06-27-github-actions-update-on-oidc-integration-with-aws/
variable "github_thumbprint_list" {
type = list(string)
description = "Github Thumbprint list"
default = [
"6938fd4d98bab03faadb97b34396831e3780aea1",
"1c58a3a8518e8759bf075b76b750d4f2df264fcd"
]
}

variable "service_mappings" {
description = "Service mapping to Github repository and ECR image name"
type = map(object({
github_repo_name = string
ecr_image_name = string
}))

default = {
"dispatch-service" = {
github_repo_name = "SRGSSR/pillarbox-event-dispatcher"
ecr_image_name = "pillarbox-event-dispatcher"
}
"data-transfer-service" = {
github_repo_name = "SRGSSR/pillarbox-monitoring-transfer"
ecr_image_name = "pillarbox-monitoring-transfer"
}
}
}

0 comments on commit 75d06fa

Please sign in to comment.