Skip to content

Commit 53dbcbd

Browse files
committed
eli-445 adding github role bootstrap role policies
1 parent 1d255e5 commit 53dbcbd

1 file changed

Lines changed: 149 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# IAM management policy – scoped to project resources
2+
resource "aws_iam_policy" "iam_bootstrap_iam_management" {
3+
name = "${upper(var.project_name)}-iam-bootstrap-iam-management"
4+
description = "Allows the IAM bootstrap role to manage project IAM resources"
5+
path = "/service-policies/"
6+
7+
policy = data.aws_iam_policy_document.iam_bootstrap_iam_management.json
8+
9+
tags = merge(local.tags, { Name = "${upper(var.project_name)}-iam-bootstrap-iam-management" })
10+
}
11+
12+
data "aws_iam_policy_document" "iam_bootstrap_iam_management" {
13+
# Full IAM access for project-scoped resources
14+
statement {
15+
sid = "IamManageProjectResources"
16+
effect = "Allow"
17+
actions = [
18+
"iam:GetRole*",
19+
"iam:GetPolicy*",
20+
"iam:ListRole*",
21+
"iam:ListPolicies",
22+
"iam:ListAttachedRolePolicies",
23+
"iam:ListPolicyVersions",
24+
"iam:ListPolicyTags",
25+
"iam:ListOpenIDConnectProviders",
26+
"iam:ListOpenIDConnectProviderTags",
27+
"iam:GetOpenIDConnectProvider",
28+
"iam:CreateRole",
29+
"iam:DeleteRole",
30+
"iam:UpdateRole",
31+
"iam:UpdateAssumeRolePolicy",
32+
"iam:PutRolePolicy",
33+
"iam:PutRolePermissionsBoundary",
34+
"iam:AttachRolePolicy",
35+
"iam:DetachRolePolicy",
36+
"iam:CreatePolicy",
37+
"iam:CreatePolicyVersion",
38+
"iam:DeletePolicy",
39+
"iam:DeletePolicyVersion",
40+
"iam:SetDefaultPolicyVersion",
41+
"iam:TagRole",
42+
"iam:TagPolicy",
43+
"iam:UntagRole",
44+
"iam:UntagPolicy",
45+
"iam:PassRole",
46+
"iam:TagOpenIDConnectProvider",
47+
"iam:UntagOpenIDConnectProvider",
48+
"iam:CreateOpenIDConnectProvider",
49+
"iam:DeleteOpenIDConnectProvider",
50+
"iam:UpdateOpenIDConnectProviderThumbprint",
51+
"iam:AddClientIDToOpenIDConnectProvider",
52+
"iam:RemoveClientIDFromOpenIDConnectProvider",
53+
]
54+
resources = [
55+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/service-roles/github-actions-api-deployment-role",
56+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/service-roles/github-actions-iam-bootstrap-role",
57+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.project_name}-terraform-developer-role",
58+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/terraform-developer-role",
59+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/${upper(var.project_name)}-*",
60+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/${lower(var.project_name)}-*",
61+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/service-policies/*",
62+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/${local.stack_name}-*",
63+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/token.actions.githubusercontent.com",
64+
]
65+
}
66+
67+
# Read-only IAM access for Terraform plan/discovery
68+
statement {
69+
sid = "IamReadOnly"
70+
effect = "Allow"
71+
actions = [
72+
"iam:Get*",
73+
"iam:List*",
74+
]
75+
resources = ["*"]
76+
}
77+
78+
# DENY: Prevent modifying the bootstrap role itself
79+
statement {
80+
sid = "DenySelfModification"
81+
effect = "Deny"
82+
actions = [
83+
"iam:AttachRolePolicy",
84+
"iam:DetachRolePolicy",
85+
"iam:PutRolePolicy",
86+
"iam:DeleteRolePolicy",
87+
"iam:UpdateAssumeRolePolicy",
88+
"iam:PutRolePermissionsBoundary",
89+
"iam:DeleteRolePermissionsBoundary",
90+
]
91+
resources = [
92+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/service-roles/github-actions-iam-bootstrap-role",
93+
]
94+
}
95+
96+
# DENY: Prevent modifying the bootstrap permissions boundary
97+
statement {
98+
sid = "DenyBootstrapBoundaryModification"
99+
effect = "Deny"
100+
actions = [
101+
"iam:CreatePolicyVersion",
102+
"iam:DeletePolicy",
103+
"iam:DeletePolicyVersion",
104+
"iam:SetDefaultPolicyVersion",
105+
]
106+
resources = [
107+
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/${lower(var.project_name)}-iam-bootstrap-permissions-boundary",
108+
]
109+
}
110+
}
111+
112+
# Terraform state management policy
113+
resource "aws_iam_policy" "iam_bootstrap_terraform_state" {
114+
name = "${upper(var.project_name)}-iam-bootstrap-terraform-state"
115+
description = "Allows the IAM bootstrap role to manage Terraform state for the iams-developer-roles stack"
116+
path = "/service-policies/"
117+
118+
policy = data.aws_iam_policy_document.iam_bootstrap_terraform_state.json
119+
120+
tags = merge(local.tags, { Name = "${upper(var.project_name)}-iam-bootstrap-terraform-state" })
121+
}
122+
123+
data "aws_iam_policy_document" "iam_bootstrap_terraform_state" {
124+
# S3 state bucket access
125+
statement {
126+
sid = "TerraformStateS3Access"
127+
effect = "Allow"
128+
actions = [
129+
"s3:ListBucket",
130+
"s3:GetObject",
131+
"s3:PutObject",
132+
"s3:DeleteObject",
133+
]
134+
resources = [
135+
"${local.terraform_state_bucket_arn}",
136+
"${local.terraform_state_bucket_arn}/*",
137+
]
138+
}
139+
}
140+
141+
resource "aws_iam_role_policy_attachment" "iam_bootstrap_iam_management" {
142+
role = aws_iam_role.github_actions_iam_bootstrap.name
143+
policy_arn = aws_iam_policy.iam_bootstrap_iam_management.arn
144+
}
145+
146+
resource "aws_iam_role_policy_attachment" "iam_bootstrap_terraform_state" {
147+
role = aws_iam_role.github_actions_iam_bootstrap.name
148+
policy_arn = aws_iam_policy.iam_bootstrap_terraform_state.arn
149+
}

0 commit comments

Comments
 (0)