Skip to content

Commit 4372f3c

Browse files
authored
[eks/alb-controller] Update ALB controller IAM policy (cloudposse/terraform-aws-components#821)
1 parent f47df41 commit 4372f3c

File tree

4 files changed

+302
-306
lines changed

4 files changed

+302
-306
lines changed

src/CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
## PR [#821](https://github.com/cloudposse/terraform-aws-components/pull/821)
2+
3+
### Update IAM Policy and Change How it is Managed
4+
5+
The ALB controller needs a lot of permissions and has a complex IAM policy.
6+
For this reason, the project releases a complete JSON policy document that is
7+
updated as needed.
8+
9+
In this release:
10+
11+
1. We have updated the policy to the one distributed with version 2.6.0 of the ALB controller. This fixes an issue
12+
where the controller was not able to create the service-linked role for the Elastic Load Balancing service.
13+
2. To ease maintenance, we have moved the policy document to a separate file,
14+
`distributed-iam-policy.tf` and made it easy to update or override.
15+
16+
17+
#### Gov Cloud and China Regions
18+
19+
Actually, the project releases 3 policy documents, one for each of the
20+
three AWS partitions: `aws`, `aws-cn`, and `aws-us-gov`. For simplicity,
21+
this module only uses the `aws` partition policy. If you are in another
22+
partition, you can create a `distributed-iam-policy_override.tf` file in your
23+
directory and override the `distributed_iam_policy_overridable` local
24+
variable with the policy document for your partition.

src/README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ This component creates a Helm release for [alb-controller](https://github.com/ku
66
in the context of AWS, provisions and manages ALBs and NLBs based on Service and Ingress annotations.
77
This module also can (and is recommended to) provision a default IngressClass.
88

9+
### Special note about upgrading
10+
11+
When upgrading the chart version, check to see if the IAM policy for the service account needs to be updated.
12+
If it does, update the policy in the `distributed-iam-policy.tf` file.
13+
Probably the easiest way to check if it needs updating is to simply download the policy from
14+
https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json
15+
and compare it to the policy in `distributed-iam-policy.tf`.
16+
917
## Usage
1018

1119
**Stack Level**: Regional
@@ -27,7 +35,9 @@ components:
2735
vars:
2836
chart: aws-load-balancer-controller
2937
chart_repository: https://aws.github.io/eks-charts
30-
chart_version: "1.4.5"
38+
# IMPORTANT: When updating the chart version, check to see if the IAM policy for the service account.
39+
# needs to be updated, and if it does, update the policy in the `distributed-iam-policy.tf` file.
40+
chart_version: "1.6.0"
3141
create_namespace: true
3242
kubernetes_namespace: alb-controller
3343
# this feature causes inconsistent final plans
@@ -67,7 +77,7 @@ components:
6777
6878
| Name | Source | Version |
6979
|------|--------|---------|
70-
| <a name="module_alb_controller"></a> [alb\_controller](#module\_alb\_controller) | cloudposse/helm-release/aws | 0.9.1 |
80+
| <a name="module_alb_controller"></a> [alb\_controller](#module\_alb\_controller) | cloudposse/helm-release/aws | 0.9.3 |
7181
| <a name="module_eks"></a> [eks](#module\_eks) | cloudposse/stack-config/yaml//modules/remote-state | 1.5.0 |
7282
| <a name="module_iam_roles"></a> [iam\_roles](#module\_iam\_roles) | ../../account-map/modules/iam-roles | n/a |
7383
| <a name="module_this"></a> [this](#module\_this) | cloudposse/label/null | 0.25.0 |

src/distributed-iam-policy.tf

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
2+
# The kubernetes-sigs/aws-load-balancer-controller/ project distributes the
3+
# AWS IAM policy that is required for the AWS Load Balancer Controller as a JSON
4+
# download at https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v<VERSION>/docs/install/iam_policy.json
5+
# See https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/deploy/installation/#option-a-recommended-iam-roles-for-service-accounts-irsa for details.
6+
7+
# We could directly use the URL to download and install the policy at runtime,
8+
# via the cloudposse/helm-release/aws module's ` iam_source_json_url` input,
9+
# but that lacks transparency and auditability. It also does not give us a chance
10+
# to make changes in response to bugs, such as
11+
# https://github.com/kubernetes-sigs/aws-load-balancer-controller/issues/2692#issuecomment-1426242236
12+
#
13+
# So we download the policy and insert it here as a local variable.
14+
15+
locals {
16+
# To update, just replace everything between the two "EOT"s with the contents of the downloaded JSON file.
17+
# Below is the policy as of version 2.6.0, downloaded from
18+
# https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.6.0/docs/install/iam_policy.json
19+
# This policy is for the `aws` partition. Override distributed_iam_policy_overridable for other partitions.
20+
distributed_iam_policy_overridable = <<EOT
21+
{
22+
"Version": "2012-10-17",
23+
"Statement": [
24+
{
25+
"Effect": "Allow",
26+
"Action": [
27+
"iam:CreateServiceLinkedRole"
28+
],
29+
"Resource": "*",
30+
"Condition": {
31+
"StringEquals": {
32+
"iam:AWSServiceName": "elasticloadbalancing.amazonaws.com"
33+
}
34+
}
35+
},
36+
{
37+
"Effect": "Allow",
38+
"Action": [
39+
"ec2:DescribeAccountAttributes",
40+
"ec2:DescribeAddresses",
41+
"ec2:DescribeAvailabilityZones",
42+
"ec2:DescribeInternetGateways",
43+
"ec2:DescribeVpcs",
44+
"ec2:DescribeVpcPeeringConnections",
45+
"ec2:DescribeSubnets",
46+
"ec2:DescribeSecurityGroups",
47+
"ec2:DescribeInstances",
48+
"ec2:DescribeNetworkInterfaces",
49+
"ec2:DescribeTags",
50+
"ec2:GetCoipPoolUsage",
51+
"ec2:DescribeCoipPools",
52+
"elasticloadbalancing:DescribeLoadBalancers",
53+
"elasticloadbalancing:DescribeLoadBalancerAttributes",
54+
"elasticloadbalancing:DescribeListeners",
55+
"elasticloadbalancing:DescribeListenerCertificates",
56+
"elasticloadbalancing:DescribeSSLPolicies",
57+
"elasticloadbalancing:DescribeRules",
58+
"elasticloadbalancing:DescribeTargetGroups",
59+
"elasticloadbalancing:DescribeTargetGroupAttributes",
60+
"elasticloadbalancing:DescribeTargetHealth",
61+
"elasticloadbalancing:DescribeTags"
62+
],
63+
"Resource": "*"
64+
},
65+
{
66+
"Effect": "Allow",
67+
"Action": [
68+
"cognito-idp:DescribeUserPoolClient",
69+
"acm:ListCertificates",
70+
"acm:DescribeCertificate",
71+
"iam:ListServerCertificates",
72+
"iam:GetServerCertificate",
73+
"waf-regional:GetWebACL",
74+
"waf-regional:GetWebACLForResource",
75+
"waf-regional:AssociateWebACL",
76+
"waf-regional:DisassociateWebACL",
77+
"wafv2:GetWebACL",
78+
"wafv2:GetWebACLForResource",
79+
"wafv2:AssociateWebACL",
80+
"wafv2:DisassociateWebACL",
81+
"shield:GetSubscriptionState",
82+
"shield:DescribeProtection",
83+
"shield:CreateProtection",
84+
"shield:DeleteProtection"
85+
],
86+
"Resource": "*"
87+
},
88+
{
89+
"Effect": "Allow",
90+
"Action": [
91+
"ec2:AuthorizeSecurityGroupIngress",
92+
"ec2:RevokeSecurityGroupIngress"
93+
],
94+
"Resource": "*"
95+
},
96+
{
97+
"Effect": "Allow",
98+
"Action": [
99+
"ec2:CreateSecurityGroup"
100+
],
101+
"Resource": "*"
102+
},
103+
{
104+
"Effect": "Allow",
105+
"Action": [
106+
"ec2:CreateTags"
107+
],
108+
"Resource": "arn:aws:ec2:*:*:security-group/*",
109+
"Condition": {
110+
"StringEquals": {
111+
"ec2:CreateAction": "CreateSecurityGroup"
112+
},
113+
"Null": {
114+
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
115+
}
116+
}
117+
},
118+
{
119+
"Effect": "Allow",
120+
"Action": [
121+
"ec2:CreateTags",
122+
"ec2:DeleteTags"
123+
],
124+
"Resource": "arn:aws:ec2:*:*:security-group/*",
125+
"Condition": {
126+
"Null": {
127+
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
128+
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
129+
}
130+
}
131+
},
132+
{
133+
"Effect": "Allow",
134+
"Action": [
135+
"ec2:AuthorizeSecurityGroupIngress",
136+
"ec2:RevokeSecurityGroupIngress",
137+
"ec2:DeleteSecurityGroup"
138+
],
139+
"Resource": "*",
140+
"Condition": {
141+
"Null": {
142+
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
143+
}
144+
}
145+
},
146+
{
147+
"Effect": "Allow",
148+
"Action": [
149+
"elasticloadbalancing:CreateLoadBalancer",
150+
"elasticloadbalancing:CreateTargetGroup"
151+
],
152+
"Resource": "*",
153+
"Condition": {
154+
"Null": {
155+
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
156+
}
157+
}
158+
},
159+
{
160+
"Effect": "Allow",
161+
"Action": [
162+
"elasticloadbalancing:CreateListener",
163+
"elasticloadbalancing:DeleteListener",
164+
"elasticloadbalancing:CreateRule",
165+
"elasticloadbalancing:DeleteRule"
166+
],
167+
"Resource": "*"
168+
},
169+
{
170+
"Effect": "Allow",
171+
"Action": [
172+
"elasticloadbalancing:AddTags",
173+
"elasticloadbalancing:RemoveTags"
174+
],
175+
"Resource": [
176+
"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
177+
"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
178+
"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
179+
],
180+
"Condition": {
181+
"Null": {
182+
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
183+
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
184+
}
185+
}
186+
},
187+
{
188+
"Effect": "Allow",
189+
"Action": [
190+
"elasticloadbalancing:AddTags",
191+
"elasticloadbalancing:RemoveTags"
192+
],
193+
"Resource": [
194+
"arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
195+
"arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
196+
"arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
197+
"arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
198+
]
199+
},
200+
{
201+
"Effect": "Allow",
202+
"Action": [
203+
"elasticloadbalancing:ModifyLoadBalancerAttributes",
204+
"elasticloadbalancing:SetIpAddressType",
205+
"elasticloadbalancing:SetSecurityGroups",
206+
"elasticloadbalancing:SetSubnets",
207+
"elasticloadbalancing:DeleteLoadBalancer",
208+
"elasticloadbalancing:ModifyTargetGroup",
209+
"elasticloadbalancing:ModifyTargetGroupAttributes",
210+
"elasticloadbalancing:DeleteTargetGroup"
211+
],
212+
"Resource": "*",
213+
"Condition": {
214+
"Null": {
215+
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
216+
}
217+
}
218+
},
219+
{
220+
"Effect": "Allow",
221+
"Action": [
222+
"elasticloadbalancing:AddTags"
223+
],
224+
"Resource": [
225+
"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
226+
"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
227+
"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
228+
],
229+
"Condition": {
230+
"StringEquals": {
231+
"elasticloadbalancing:CreateAction": [
232+
"CreateTargetGroup",
233+
"CreateLoadBalancer"
234+
]
235+
},
236+
"Null": {
237+
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
238+
}
239+
}
240+
},
241+
{
242+
"Effect": "Allow",
243+
"Action": [
244+
"elasticloadbalancing:RegisterTargets",
245+
"elasticloadbalancing:DeregisterTargets"
246+
],
247+
"Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"
248+
},
249+
{
250+
"Effect": "Allow",
251+
"Action": [
252+
"elasticloadbalancing:SetWebAcl",
253+
"elasticloadbalancing:ModifyListener",
254+
"elasticloadbalancing:AddListenerCertificates",
255+
"elasticloadbalancing:RemoveListenerCertificates",
256+
"elasticloadbalancing:ModifyRule"
257+
],
258+
"Resource": "*"
259+
}
260+
]
261+
}
262+
EOT
263+
}

0 commit comments

Comments
 (0)