Coverage for gco/stacks/aws_load_balancer_controller_policy.py: 83.33%
10 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-30 21:22 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-30 21:22 +0000
1"""Pinned AWS Load Balancer Controller v3.4.2 IAM policy.
3The JSON body is the exact upstream ``docs/install/iam_policy.json`` from tag
4``v3.4.2``. Only the ARN partition is substituted at synth time so the same
5policy works in every AWS partition supported by GCO.
7Source:
8https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/v3.4.2/docs/install/iam_policy.json
9"""
11from __future__ import annotations
13import json
14from typing import Any
16_AWS_LOAD_BALANCER_CONTROLLER_POLICY_V3_4_2 = r"""
17{
18 "Version": "2012-10-17",
19 "Statement": [
20 {
21 "Effect": "Allow",
22 "Action": [
23 "iam:CreateServiceLinkedRole"
24 ],
25 "Resource": "*",
26 "Condition": {
27 "StringEquals": {
28 "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com"
29 }
30 }
31 },
32 {
33 "Effect": "Allow",
34 "Action": [
35 "ec2:DescribeAccountAttributes",
36 "ec2:DescribeAddresses",
37 "ec2:DescribeAvailabilityZones",
38 "ec2:DescribeInternetGateways",
39 "ec2:DescribeVpcs",
40 "ec2:DescribeVpcPeeringConnections",
41 "ec2:DescribeSubnets",
42 "ec2:DescribeSecurityGroups",
43 "ec2:DescribeInstances",
44 "ec2:DescribeNetworkInterfaces",
45 "ec2:DescribeTags",
46 "ec2:GetCoipPoolUsage",
47 "ec2:DescribeCoipPools",
48 "ec2:GetSecurityGroupsForVpc",
49 "ec2:DescribeIpamPools",
50 "ec2:DescribeRouteTables",
51 "elasticloadbalancing:DescribeLoadBalancers",
52 "elasticloadbalancing:DescribeLoadBalancerAttributes",
53 "elasticloadbalancing:DescribeListeners",
54 "elasticloadbalancing:DescribeListenerCertificates",
55 "elasticloadbalancing:DescribeSSLPolicies",
56 "elasticloadbalancing:DescribeRules",
57 "elasticloadbalancing:DescribeTargetGroups",
58 "elasticloadbalancing:DescribeTargetGroupAttributes",
59 "elasticloadbalancing:DescribeTargetHealth",
60 "elasticloadbalancing:DescribeTags",
61 "elasticloadbalancing:DescribeTrustStores",
62 "elasticloadbalancing:DescribeListenerAttributes",
63 "elasticloadbalancing:DescribeCapacityReservation"
64 ],
65 "Resource": "*"
66 },
67 {
68 "Effect": "Allow",
69 "Action": [
70 "cognito-idp:DescribeUserPoolClient",
71 "acm:ListCertificates",
72 "acm:DescribeCertificate",
73 "iam:ListServerCertificates",
74 "iam:GetServerCertificate",
75 "waf-regional:GetWebACL",
76 "waf-regional:GetWebACLForResource",
77 "waf-regional:AssociateWebACL",
78 "waf-regional:DisassociateWebACL",
79 "wafv2:GetWebACL",
80 "wafv2:GetWebACLForResource",
81 "wafv2:AssociateWebACL",
82 "wafv2:DisassociateWebACL",
83 "shield:GetSubscriptionState",
84 "shield:DescribeProtection",
85 "shield:CreateProtection",
86 "shield:DeleteProtection"
87 ],
88 "Resource": "*"
89 },
90 {
91 "Effect": "Allow",
92 "Action": [
93 "ec2:AuthorizeSecurityGroupIngress",
94 "ec2:RevokeSecurityGroupIngress"
95 ],
96 "Resource": "*"
97 },
98 {
99 "Effect": "Allow",
100 "Action": [
101 "ec2:CreateSecurityGroup"
102 ],
103 "Resource": "*"
104 },
105 {
106 "Effect": "Allow",
107 "Action": [
108 "ec2:CreateTags"
109 ],
110 "Resource": "arn:aws:ec2:*:*:security-group/*",
111 "Condition": {
112 "StringEquals": {
113 "ec2:CreateAction": "CreateSecurityGroup"
114 },
115 "Null": {
116 "aws:RequestTag/elbv2.k8s.aws/cluster": "false"
117 }
118 }
119 },
120 {
121 "Effect": "Allow",
122 "Action": [
123 "ec2:CreateTags",
124 "ec2:DeleteTags"
125 ],
126 "Resource": "arn:aws:ec2:*:*:security-group/*",
127 "Condition": {
128 "Null": {
129 "aws:RequestTag/elbv2.k8s.aws/cluster": "true",
130 "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
131 }
132 }
133 },
134 {
135 "Effect": "Allow",
136 "Action": [
137 "ec2:AuthorizeSecurityGroupIngress",
138 "ec2:RevokeSecurityGroupIngress",
139 "ec2:DeleteSecurityGroup"
140 ],
141 "Resource": "*",
142 "Condition": {
143 "Null": {
144 "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
145 }
146 }
147 },
148 {
149 "Effect": "Allow",
150 "Action": [
151 "elasticloadbalancing:CreateLoadBalancer",
152 "elasticloadbalancing:CreateTargetGroup"
153 ],
154 "Resource": "*",
155 "Condition": {
156 "Null": {
157 "aws:RequestTag/elbv2.k8s.aws/cluster": "false"
158 }
159 }
160 },
161 {
162 "Effect": "Allow",
163 "Action": [
164 "elasticloadbalancing:CreateListener",
165 "elasticloadbalancing:DeleteListener",
166 "elasticloadbalancing:CreateRule",
167 "elasticloadbalancing:DeleteRule"
168 ],
169 "Resource": "*"
170 },
171 {
172 "Effect": "Allow",
173 "Action": [
174 "elasticloadbalancing:AddTags",
175 "elasticloadbalancing:RemoveTags"
176 ],
177 "Resource": [
178 "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
179 "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
180 "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
181 ],
182 "Condition": {
183 "Null": {
184 "aws:RequestTag/elbv2.k8s.aws/cluster": "true",
185 "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
186 }
187 }
188 },
189 {
190 "Effect": "Allow",
191 "Action": [
192 "elasticloadbalancing:AddTags",
193 "elasticloadbalancing:RemoveTags"
194 ],
195 "Resource": [
196 "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
197 "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
198 "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
199 "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
200 ]
201 },
202 {
203 "Effect": "Allow",
204 "Action": [
205 "elasticloadbalancing:ModifyLoadBalancerAttributes",
206 "elasticloadbalancing:SetIpAddressType",
207 "elasticloadbalancing:SetSecurityGroups",
208 "elasticloadbalancing:SetSubnets",
209 "elasticloadbalancing:DeleteLoadBalancer",
210 "elasticloadbalancing:ModifyTargetGroup",
211 "elasticloadbalancing:ModifyTargetGroupAttributes",
212 "elasticloadbalancing:DeleteTargetGroup",
213 "elasticloadbalancing:ModifyListenerAttributes",
214 "elasticloadbalancing:ModifyCapacityReservation",
215 "elasticloadbalancing:ModifyIpPools"
216 ],
217 "Resource": "*",
218 "Condition": {
219 "Null": {
220 "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
221 }
222 }
223 },
224 {
225 "Effect": "Allow",
226 "Action": [
227 "elasticloadbalancing:AddTags"
228 ],
229 "Resource": [
230 "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
231 "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
232 "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
233 ],
234 "Condition": {
235 "StringEquals": {
236 "elasticloadbalancing:CreateAction": [
237 "CreateTargetGroup",
238 "CreateLoadBalancer"
239 ]
240 },
241 "Null": {
242 "aws:RequestTag/elbv2.k8s.aws/cluster": "false"
243 }
244 }
245 },
246 {
247 "Effect": "Allow",
248 "Action": [
249 "elasticloadbalancing:RegisterTargets",
250 "elasticloadbalancing:DeregisterTargets"
251 ],
252 "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"
253 },
254 {
255 "Effect": "Allow",
256 "Action": [
257 "elasticloadbalancing:SetWebAcl",
258 "elasticloadbalancing:ModifyListener",
259 "elasticloadbalancing:AddListenerCertificates",
260 "elasticloadbalancing:RemoveListenerCertificates",
261 "elasticloadbalancing:ModifyRule",
262 "elasticloadbalancing:SetRulePriorities"
263 ],
264 "Resource": "*"
265 }
266 ]
267}
268"""
271def aws_load_balancer_controller_policy_document(partition: str) -> dict[str, Any]:
272 """Return a fresh policy document with only ARN partitions substituted."""
273 if not partition or ":" in partition: 273 ↛ 274line 273 didn't jump to line 274 because the condition on line 273 was never true
274 raise ValueError(f"Invalid AWS partition: {partition!r}")
275 document = _AWS_LOAD_BALANCER_CONTROLLER_POLICY_V3_4_2.replace("arn:aws:", f"arn:{partition}:")
276 parsed = json.loads(document)
277 if not isinstance(parsed, dict): # pragma: no cover - pinned literal invariant
278 raise RuntimeError("Pinned AWS Load Balancer Controller policy is not an object")
279 return parsed