Skip to content

Commit 5184788

Browse files
Added Github OIDC Provider for short lived AWS creds
1 parent 08292dd commit 5184788

3 files changed

Lines changed: 241 additions & 0 deletions

File tree

infrastructure/oidc.tf

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
resource "aws_iam_openid_connect_provider" "github" {
2+
url = "https://token.actions.githubusercontent.com"
3+
client_id_list = ["sts.amazonaws.com"]
4+
thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
5+
}
6+
7+
resource "aws_iam_role" "github_actions" {
8+
name = "portfolio-github-actions-role"
9+
10+
assume_role_policy = jsonencode({
11+
Version = "2012-10=17"
12+
Statement = [{
13+
Effect = "Allow"
14+
Principal = {
15+
Federated = aws_iam_openid_connect_provider.github.arn
16+
}
17+
Action = "sts:AssumeRoleWithWebIdentity"
18+
Condition = {
19+
StringEquals = {
20+
"token.actions.githubusercontent.com:aud" = "sts.amazonaws.com"
21+
}
22+
StringLike = {
23+
"token.actions.githubusercontent.com:sub" = "repo:${var.github_repo}:ref:refs/heads/main"
24+
}
25+
}
26+
}]
27+
})
28+
}
29+
30+
resource "aws_iam_policy" "github_actions_s3" {
31+
name = "portfolio-github-actions-s3"
32+
33+
policy = jsonencode({
34+
Version = "2012-10-17"
35+
Statement = [
36+
{
37+
# For Frontend Bucket
38+
Effect = "Allow"
39+
Action = [
40+
"s3:PutObject",
41+
"s3:DeleteObject",
42+
"s3:GetObject",
43+
"s3:ListBucket"
44+
]
45+
Resource = [
46+
"arn:aws:s3:::seturaman-portfolio-frontend",
47+
"arn:aws:s3:::seturaman-portfolio-frontend/*"
48+
]
49+
},
50+
{
51+
# Terraform state bucket
52+
Effect = "Allow"
53+
Action = [
54+
"s3:GetObject",
55+
"s3:PutObject",
56+
"s3:ListBucket"
57+
]
58+
Resource = [
59+
"arn:aws:s3:::seturaman-portfolio-terraform-state",
60+
"arn:aws:s3:::seturaman-portfolio-terraform-state/*"
61+
]
62+
}
63+
]
64+
})
65+
}
66+
67+
resource "aws_iam_policy" "github_actions_cloudfront" {
68+
name = "portfolio-github-actions-cloudfront"
69+
70+
policy = jsonencode({
71+
Version = "2012-10-17"
72+
Statement = [{
73+
# For the CDN through cloudfront
74+
Effect = "Allow"
75+
Action = [
76+
"cloudfront:CreateInvalidation",
77+
"cloudfront:GetDistribution",
78+
"cloudfront:GetInvalidation"
79+
]
80+
Resource = "arn:aws:cloudfront::${var.aws_account_id}:distribution/*"
81+
}]
82+
})
83+
}
84+
85+
resource "aws_iam_policy" "github_actions_lambda" {
86+
name = "portfolio-github-actions-lambda"
87+
88+
policy = jsonencode({
89+
Version = "2012-10-17"
90+
Statement = [{
91+
# The mail sending lambda permission
92+
Effect = "Allow"
93+
Action = [
94+
"lambda:UpdateFunctionCode",
95+
"lambda:GetFunction",
96+
"lambda:GetFunctionConfiguration"
97+
]
98+
Resource = "arn:aws:lambda:${var.aws_region}:${var.aws_account_id}:function:portfolio-contact"
99+
}]
100+
})
101+
}
102+
103+
# For terraform Apply in the deploy script
104+
resource "aws_iam_policy" "github_actions_terraform" {
105+
name = "portfolio-github-actions-terraform"
106+
107+
policy = jsonencode({
108+
Version = "2012-10-17"
109+
Statement = [
110+
{
111+
Effect = "Allow"
112+
Action = [
113+
# IAM
114+
"iam:GetRole",
115+
"iam:CreateRole",
116+
"iam:UpdateRole",
117+
"iam:DeleteRole",
118+
"iam:PutRolePolicy",
119+
"iam:GetRolePolicy",
120+
"iam:DeleteRolePolicy",
121+
"iam:AttachRolePolicy",
122+
"iam:DetachRolePolicy",
123+
"iam:ListRolePolicies",
124+
"iam:ListAttachedRolePolicies",
125+
"iam:GetPolicy",
126+
"iam:CreatePolicy",
127+
"iam:DeletePolicy",
128+
"iam:GetPolicyVersion",
129+
"iam:CreatePolicyVersion",
130+
"iam:ListPolicyVersions",
131+
"iam:DeletePolicyVersion",
132+
"iam:GetOpenIDConnectProvider",
133+
"iam:CreateOpenIDConnectProvider",
134+
"iam:DeleteOpenIDConnectProvider",
135+
"iam:TagOpenIDConnectProvider"
136+
]
137+
Resource = "*"
138+
},
139+
{
140+
Effect = "Allow"
141+
Action = [
142+
# API Gateway
143+
"apigateway:GET",
144+
"apigateway:POST",
145+
"apigateway:PUT",
146+
"apigateway:PATCH",
147+
"apigateway:DELETE",
148+
"apigateway:TAG"
149+
]
150+
Resource = "*"
151+
},
152+
{
153+
Effect = "Allow"
154+
Action = [
155+
# ACM
156+
"acm:RequestCertificate",
157+
"acm:DescribeCertificate",
158+
"acm:DeleteCertificate",
159+
"acm:ListCertificates",
160+
"acm:GetCertificate",
161+
"acm:AddTagsToCertificate",
162+
"acm:ListTagsForCertificate"
163+
]
164+
Resource = "*"
165+
},
166+
{
167+
Effect = "Allow"
168+
Action = [
169+
# Lambda
170+
"lambda:CreateFunction",
171+
"lambda:DeleteFunction",
172+
"lambda:GetFunction",
173+
"lambda:GetFunctionConfiguration",
174+
"lambda:UpdateFunctionCode",
175+
"lambda:UpdateFunctionConfiguration",
176+
"lambda:AddPermission",
177+
"lambda:RemovePermission",
178+
"lambda:GetPolicy",
179+
"lambda:ListVersionsByFunction",
180+
"lambda:PublishVersion",
181+
"lambda:TagResource",
182+
"lambda:ListTags"
183+
]
184+
Resource = "*"
185+
},
186+
{
187+
Effect = "Allow"
188+
Action = [
189+
# CloudFront
190+
"cloudfront:CreateDistribution",
191+
"cloudfront:GetDistribution",
192+
"cloudfront:UpdateDistribution",
193+
"cloudfront:DeleteDistribution",
194+
"cloudfront:CreateOriginAccessControl",
195+
"cloudfront:GetOriginAccessControl",
196+
"cloudfront:UpdateOriginAccessControl",
197+
"cloudfront:DeleteOriginAccessControl",
198+
"cloudfront:TagResource",
199+
"cloudfront:ListTagsForResource"
200+
]
201+
Resource = "*"
202+
}
203+
]
204+
})
205+
}
206+
207+
resource "aws_iam_role_policy_attachment" "github_actions_s3" {
208+
role = aws_iam_role.github_actions.name
209+
policy_arn = aws_iam_policy.github_actions_s3.arn
210+
}
211+
212+
resource "aws_iam_role_policy_attachment" "github_actions_cloudfront" {
213+
role = aws_iam_role.github_actions.name
214+
policy_arn = aws_iam_policy.github_actions_cloudfront.arn
215+
}
216+
217+
resource "aws_iam_role_policy_attachment" "github_actions_lambda" {
218+
role = aws_iam_role.github_actions.name
219+
policy_arn = aws_iam_policy.github_actions_lambda.arn
220+
}
221+
222+
resource "aws_iam_role_policy_attachment" "github_actions_terraform" {
223+
role = aws_iam_role.github_actions.name
224+
policy_arn = aws_iam_policy.github_actions_terraform.arn
225+
}

infrastructure/outputs.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,8 @@ output "api_custom_domain" {
2828
description = "API Gateway regional domain name. Used as CNAME target in Cloudflare for api.seturaman.me"
2929
value = aws_apigatewayv2_domain_name.api.domain_name_configuration[0].target_domain_name
3030
}
31+
32+
output "github_actions_role_arn" {
33+
description = "IAM role ARN for GitHub Actions OIDC. Add as AWS_GITHUB_ACTIONS_ROLE_ARN in GitHub secrets."
34+
value = aws_iam_role.github_actions
35+
}

infrastructure/variables.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,14 @@ variable "aws_account_id" {
3030
type = string
3131
sensitive = true
3232
}
33+
34+
variable "github_repo" {
35+
description = "GitHub repository in owner/repo format. Used to scope OIDC trust policy to this repo only."
36+
type = string
37+
}
38+
39+
variable "aws_region" {
40+
description = "AWS region used for scoping IAM policy resource ARNs."
41+
type = string
42+
default = "ap-south-1"
43+
}

0 commit comments

Comments
 (0)