Skip to content

Commit 75d06fa

Browse files
committed
feat: centralize iam role setup for github actions
- 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.
1 parent d8d2610 commit 75d06fa

File tree

7 files changed

+234
-98
lines changed

7 files changed

+234
-98
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ The project is split into four main Terraform configurations:
119119
Monitoring infrastructure. **This applies to both dev and prod environments**. You can switch
120120
between workspaces (as mentioned earlier) to deploy infrastructure in either the dev or prod
121121
account.
122+
- [21-continuous-delivery][cd]: This configuration contains the definition of the IAM roles that
123+
allow access to GitHub Action for specific repositories and operations. **This applies to both
124+
dev and prod environments**. You can switch between workspaces (as mentioned earlier) to deploy
125+
infrastructure in either the dev or prod account.
122126
123127
### System Flow Overview
124128
@@ -170,3 +174,4 @@ This project is licensed under the [MIT License](LICENSE).
170174
[route-53]: /pillarbox-monitoring-terraform/10-pillarbox-monitoring-route-53
171175
[ecr]: /pillarbox-monitoring-terraform/11-pillarbox-monitoring-ecr
172176
[app]: /pillarbox-monitoring-terraform/20-pillarbox-monitoring-app
177+
[cd]: /pillarbox-monitoring-terraform/21-continuous-delivery

pillarbox-monitoring-terraform/11-pillarbox-monitoring-ecr/main.tf

Lines changed: 0 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -77,94 +77,6 @@ resource "aws_ecr_lifecycle_policy" "ecr_lifecycles" {
7777
EOF
7878
}
7979

80-
# -----------------------------------
81-
# IAM Configuration for GitHub Actions
82-
# -----------------------------------
83-
84-
## Set Up OIDC Provider
85-
86-
resource "aws_iam_openid_connect_provider" "github_actions" {
87-
# Create an IAM OIDC provider for GitHub Actions
88-
url = "https://token.actions.githubusercontent.com"
89-
client_id_list = ["sts.amazonaws.com"]
90-
thumbprint_list = var.github_thumbprint_list
91-
}
92-
93-
## Define IAM Policy Documents
94-
95-
### Assume Role Policy Document
96-
97-
data "aws_iam_policy_document" "gha_assume_policy" {
98-
# Generate policy documents for assuming IAM roles via OIDC
99-
for_each = var.ecr_repositories
100-
101-
statement {
102-
effect = "Allow"
103-
actions = ["sts:AssumeRoleWithWebIdentity"]
104-
principals {
105-
type = "Federated"
106-
identifiers = [aws_iam_openid_connect_provider.github_actions.arn]
107-
}
108-
condition {
109-
test = "StringEquals"
110-
variable = "token.actions.githubusercontent.com:aud"
111-
values = ["sts.amazonaws.com"]
112-
}
113-
condition {
114-
test = "StringLike"
115-
variable = "token.actions.githubusercontent.com:sub"
116-
values = ["repo:${each.value}:*"]
117-
}
118-
}
119-
}
120-
121-
### Permissions Policy Document
122-
123-
data "aws_iam_policy_document" "gha_policy" {
124-
# Define permissions for GitHub Actions to interact with ECR
125-
for_each = var.ecr_repositories
126-
127-
# Allow Docker login to ECR
128-
statement {
129-
sid = "AllowDockerLogin"
130-
effect = "Allow"
131-
actions = ["ecr:GetAuthorizationToken"]
132-
resources = ["*"]
133-
}
134-
135-
# Allow pushing and pulling images to/from ECR
136-
statement {
137-
sid = "AllowPushPull"
138-
effect = "Allow"
139-
actions = [
140-
"ecr:BatchGetImage",
141-
"ecr:GetDownloadUrlForLayer",
142-
"ecr:InitiateLayerUpload",
143-
"ecr:UploadLayerPart",
144-
"ecr:CompleteLayerUpload",
145-
"ecr:BatchCheckLayerAvailability",
146-
"ecr:PutImage"
147-
]
148-
resources = [aws_ecr_repository.repositories[each.key].arn]
149-
}
150-
}
151-
152-
## Create IAM Roles for GitHub Actions
153-
154-
resource "aws_iam_role" "gha_role" {
155-
# Create IAM roles for each ECR repository for GitHub Actions
156-
for_each = var.ecr_repositories
157-
158-
name = "gh-actions-role-${each.key}"
159-
assume_role_policy = data.aws_iam_policy_document.gha_assume_policy[each.key].json
160-
161-
# Attach inline policy for ECR permissions
162-
inline_policy {
163-
name = "GithubActionECRBuilds"
164-
policy = data.aws_iam_policy_document.gha_policy[each.key].json
165-
}
166-
}
167-
16880
# -----------------------------------
16981
# Cross-Account ECR Access Configuration
17082
# -----------------------------------

pillarbox-monitoring-terraform/11-pillarbox-monitoring-ecr/variables.tf

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,3 @@
1-
# See https://github.blog/changelog/2023-06-27-github-actions-update-on-oidc-integration-with-aws/
2-
variable "github_thumbprint_list" {
3-
type = list(string)
4-
description = "Github Thumbprint list"
5-
default = [
6-
"6938fd4d98bab03faadb97b34396831e3780aea1",
7-
"1c58a3a8518e8759bf075b76b750d4f2df264fcd"
8-
]
9-
}
10-
111
variable "ecr_repositories" {
122
description = "Map of ECR repository names to their associated GitHub repository"
133
type = map(string)

pillarbox-monitoring-terraform/21-continuous-delivery/.terraform.lock.hcl

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
locals {
2+
ecs_cluster_name = "${var.application_name}-cluster"
3+
is_prod = terraform.workspace == "prod"
4+
5+
default_tags = {
6+
"srg-managed-by" = "terraform"
7+
"srg-application" = var.application_name
8+
"srg-owner" = "[email protected]"
9+
"srg-businessowner" = "pillarbox"
10+
"srg-environment" = terraform.workspace
11+
}
12+
}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# -----------------------------------
2+
# Terraform Configuration
3+
# -----------------------------------
4+
5+
terraform {
6+
# Backend configuration for storing the Terraform state in S3 with DynamoDB table for state locking
7+
backend "s3" {
8+
encrypt = true
9+
bucket = "pillarbox-monitoring-tfstate"
10+
key = "terraform/21-continuous-delivery/terraform.tfstate"
11+
dynamodb_table = "pillarbox-monitoring-terraform-statelock"
12+
profile = "prod"
13+
}
14+
15+
# Specify required providers and their versions
16+
required_providers {
17+
aws = {
18+
source = "hashicorp/aws"
19+
version = "~>5.4.0"
20+
}
21+
}
22+
}
23+
24+
# -----------------------------------
25+
# AWS Provider Setup
26+
# -----------------------------------
27+
28+
provider "aws" {
29+
# Apply default tags to all AWS resources
30+
default_tags {
31+
tags = local.default_tags
32+
}
33+
}
34+
35+
# -----------------------------------
36+
# AWS Data Sources
37+
# -----------------------------------
38+
39+
# Get current AWS region
40+
data "aws_region" "current" {}
41+
42+
# Get current AWS identity
43+
data "aws_caller_identity" "current" {}
44+
45+
# -----------------------------------
46+
# IAM Configuration for GitHub Actions
47+
# -----------------------------------
48+
49+
## Set Up OIDC Provider
50+
51+
resource "aws_iam_openid_connect_provider" "github_actions" {
52+
# Create an IAM OIDC provider for GitHub Actions
53+
url = "https://token.actions.githubusercontent.com"
54+
client_id_list = ["sts.amazonaws.com"]
55+
thumbprint_list = var.github_thumbprint_list
56+
}
57+
58+
## Define IAM Policy Documents
59+
60+
### Assume Role Policy Document
61+
62+
data "aws_iam_policy_document" "gha_assume_policy" {
63+
# Generate policy documents for assuming IAM roles via OIDC
64+
for_each = var.service_mappings
65+
66+
statement {
67+
effect = "Allow"
68+
actions = ["sts:AssumeRoleWithWebIdentity"]
69+
principals {
70+
type = "Federated"
71+
identifiers = [aws_iam_openid_connect_provider.github_actions.arn]
72+
}
73+
condition {
74+
test = "StringEquals"
75+
variable = "token.actions.githubusercontent.com:aud"
76+
values = ["sts.amazonaws.com"]
77+
}
78+
condition {
79+
test = "StringLike"
80+
variable = "token.actions.githubusercontent.com:sub"
81+
values = ["repo:${each.value.github_repo_name}:*"]
82+
}
83+
}
84+
}
85+
86+
### Permissions Policy Document
87+
88+
data "aws_iam_policy_document" "gha_policy" {
89+
# Define permissions for GitHub Actions to interact with ECR and ECS
90+
for_each = var.service_mappings
91+
92+
# Allow Docker login to ECR
93+
dynamic "statement" {
94+
for_each = local.is_prod ? [1] : []
95+
96+
content {
97+
sid = "AllowDockerLogin"
98+
effect = "Allow"
99+
actions = ["ecr:GetAuthorizationToken"]
100+
resources = ["*"]
101+
}
102+
}
103+
104+
# Allow pushing and pulling images to/from ECR
105+
dynamic "statement" {
106+
for_each = local.is_prod ? [1] : []
107+
108+
content {
109+
sid = "AllowPushPull"
110+
effect = "Allow"
111+
actions = [
112+
"ecr:BatchGetImage",
113+
"ecr:GetDownloadUrlForLayer",
114+
"ecr:InitiateLayerUpload",
115+
"ecr:UploadLayerPart",
116+
"ecr:CompleteLayerUpload",
117+
"ecr:BatchCheckLayerAvailability",
118+
"ecr:PutImage"
119+
]
120+
resources = [
121+
"arn:aws:ecr:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:repository/${each.value.ecr_image_name}"
122+
]
123+
124+
}
125+
}
126+
127+
# Allow updating ECS services
128+
statement {
129+
sid = "AllowUpdateService"
130+
effect = "Allow"
131+
actions = [
132+
"ecs:UpdateService",
133+
"ecs:DescribeServices"
134+
]
135+
resources = [
136+
"arn:aws:ecs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:cluster/${local.ecs_cluster_name}",
137+
"arn:aws:ecs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:service/${local.ecs_cluster_name}/${each.key}"
138+
]
139+
}
140+
}
141+
142+
## Create IAM Roles for GitHub Actions
143+
144+
resource "aws_iam_role" "gha_role" {
145+
# Create IAM roles for each service
146+
for_each = var.service_mappings
147+
148+
name = "gh-actions-role-${each.key}"
149+
assume_role_policy = data.aws_iam_policy_document.gha_assume_policy[each.key].json
150+
151+
# Attach inline policy for ECR and ECS permissions
152+
inline_policy {
153+
name = "GithubActionPermissions"
154+
policy = data.aws_iam_policy_document.gha_policy[each.key].json
155+
}
156+
}
157+
158+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
variable "application_name" {
2+
description = "The name of the application"
3+
type = string
4+
default = "pillarbox-monitoring"
5+
}
6+
7+
# See https://github.blog/changelog/2023-06-27-github-actions-update-on-oidc-integration-with-aws/
8+
variable "github_thumbprint_list" {
9+
type = list(string)
10+
description = "Github Thumbprint list"
11+
default = [
12+
"6938fd4d98bab03faadb97b34396831e3780aea1",
13+
"1c58a3a8518e8759bf075b76b750d4f2df264fcd"
14+
]
15+
}
16+
17+
variable "service_mappings" {
18+
description = "Service mapping to Github repository and ECR image name"
19+
type = map(object({
20+
github_repo_name = string
21+
ecr_image_name = string
22+
}))
23+
24+
default = {
25+
"dispatch-service" = {
26+
github_repo_name = "SRGSSR/pillarbox-event-dispatcher"
27+
ecr_image_name = "pillarbox-event-dispatcher"
28+
}
29+
"data-transfer-service" = {
30+
github_repo_name = "SRGSSR/pillarbox-monitoring-transfer"
31+
ecr_image_name = "pillarbox-monitoring-transfer"
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)