From 732a2706b166d04e7ed1c4fda220672e53a75203 Mon Sep 17 00:00:00 2001 From: Fred Cox Date: Thu, 28 Mar 2019 22:45:12 +0200 Subject: [PATCH] Add option to add IAM policies for AWS ALB Ingress Controller --- humans.txt | 1 + pkg/apis/eksctl.io/v1alpha4/defaults.go | 3 + pkg/apis/eksctl.io/v1alpha4/types.go | 3 + pkg/apis/eksctl.io/v1alpha4/validation.go | 3 + .../v1alpha4/zz_generated.deepcopy.go | 5 ++ pkg/cfn/builder/api_test.go | 87 +++++++++++++++++++ pkg/cfn/builder/iam.go | 71 +++++++++++++++ pkg/ctl/cmdutils/nodegroup_filter_test.go | 18 ++-- pkg/ctl/cmdutils/nodegroup_flags.go | 2 + 9 files changed, 187 insertions(+), 6 deletions(-) diff --git a/humans.txt b/humans.txt index 6f5514731a..dcaa20fc94 100644 --- a/humans.txt +++ b/humans.txt @@ -37,6 +37,7 @@ Jerry Jackson @jrryjcksn Dann Church @D3nn Roli Schilter @rndstr Mitchel Humpherys @mgalgs +Fred Cox @mcfedr /* Thanks */ diff --git a/pkg/apis/eksctl.io/v1alpha4/defaults.go b/pkg/apis/eksctl.io/v1alpha4/defaults.go index 48e84111c9..0e940ef0de 100644 --- a/pkg/apis/eksctl.io/v1alpha4/defaults.go +++ b/pkg/apis/eksctl.io/v1alpha4/defaults.go @@ -51,6 +51,9 @@ func SetNodeGroupDefaults(_ int, ng *NodeGroup) error { if ng.IAM.WithAddonPolicies.ExternalDNS == nil { ng.IAM.WithAddonPolicies.ExternalDNS = NewBoolFalse() } + if ng.IAM.WithAddonPolicies.ALBIngress == nil { + ng.IAM.WithAddonPolicies.ALBIngress = NewBoolFalse() + } return nil } diff --git a/pkg/apis/eksctl.io/v1alpha4/types.go b/pkg/apis/eksctl.io/v1alpha4/types.go index 400795286f..8214e10844 100644 --- a/pkg/apis/eksctl.io/v1alpha4/types.go +++ b/pkg/apis/eksctl.io/v1alpha4/types.go @@ -327,6 +327,7 @@ func (c *ClusterConfig) NewNodeGroup() *NodeGroup { ExternalDNS: NewBoolFalse(), AppMesh: NewBoolFalse(), EBS: NewBoolFalse(), + ALBIngress: NewBoolFalse(), }, }, } @@ -437,5 +438,7 @@ type ( AppMesh *bool `json:"appMesh"` // +optional EBS *bool `json:"ebs"` + // +optional + ALBIngress *bool `json:"albIngress"` } ) diff --git a/pkg/apis/eksctl.io/v1alpha4/validation.go b/pkg/apis/eksctl.io/v1alpha4/validation.go index fd80849bd7..0d4c880489 100644 --- a/pkg/apis/eksctl.io/v1alpha4/validation.go +++ b/pkg/apis/eksctl.io/v1alpha4/validation.go @@ -31,6 +31,9 @@ func validateNodeGroupIAM(i int, ng *NodeGroup, value, fieldName, path string) e if v := ng.IAM.WithAddonPolicies.EBS; v != nil && *v { return fmt.Errorf("%s.ebs cannot be set at the same time", p) } + if v := ng.IAM.WithAddonPolicies.ALBIngress; v != nil && *v { + return fmt.Errorf("%s.albIngress cannot be set at the same time", p) + } } return nil } diff --git a/pkg/apis/eksctl.io/v1alpha4/zz_generated.deepcopy.go b/pkg/apis/eksctl.io/v1alpha4/zz_generated.deepcopy.go index 3bca5a91ae..75f7afdd4b 100644 --- a/pkg/apis/eksctl.io/v1alpha4/zz_generated.deepcopy.go +++ b/pkg/apis/eksctl.io/v1alpha4/zz_generated.deepcopy.go @@ -382,6 +382,11 @@ func (in *NodeGroupIAMAddonPolicies) DeepCopyInto(out *NodeGroupIAMAddonPolicies *out = new(bool) **out = **in } + if in.ALBIngress != nil { + in, out := &in.ALBIngress, &out.ALBIngress + *out = new(bool) + **out = **in + } return } diff --git a/pkg/cfn/builder/api_test.go b/pkg/cfn/builder/api_test.go index e087dc3d6d..215041139b 100644 --- a/pkg/cfn/builder/api_test.go +++ b/pkg/cfn/builder/api_test.go @@ -343,6 +343,7 @@ var _ = Describe("CloudFormation template builder API", func() { ExternalDNS: api.NewBoolFalse(), AppMesh: api.NewBoolFalse(), EBS: api.NewBoolFalse(), + ALBIngress: api.NewBoolFalse(), }, }, }, @@ -566,6 +567,92 @@ var _ = Describe("CloudFormation template builder API", func() { }) + Context("NodeGroupALBIngress", func() { + cfg, ng := newClusterConfigAndNodegroup(true) + + ng.IAM.WithAddonPolicies.ALBIngress = api.NewBoolTrue() + + build(cfg, "eksctl-test-megaapps-cluster", ng) + + roundtript() + + It("should have correct policies", func() { + Expect(obj.Resources).ToNot(BeEmpty()) + + Expect(obj.Resources).To(HaveKey("PolicyALBIngress")) + Expect(obj.Resources["PolicyALBIngress"].Properties.PolicyDocument.Statement).To(HaveLen(1)) + Expect(obj.Resources["PolicyALBIngress"].Properties.PolicyDocument.Statement[0].Effect).To(Equal("Allow")) + Expect(obj.Resources["PolicyALBIngress"].Properties.PolicyDocument.Statement[0].Resource).To(Equal("*")) + Expect(obj.Resources["PolicyALBIngress"].Properties.PolicyDocument.Statement[0].Action).To(Equal([]string{ + "acm:DescribeCertificate", + "acm:ListCertificates", + "acm:GetCertificate", + "ec2:AuthorizeSecurityGroupIngress", + "ec2:CreateSecurityGroup", + "ec2:CreateTags", + "ec2:DeleteTags", + "ec2:DeleteSecurityGroup", + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeInstances", + "ec2:DescribeInstanceStatus", + "ec2:DescribeInternetGateways", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeTags", + "ec2:DescribeVpcs", + "ec2:ModifyInstanceAttribute", + "ec2:ModifyNetworkInterfaceAttribute", + "ec2:RevokeSecurityGroupIngress", + "elasticloadbalancing:AddListenerCertificates", + "elasticloadbalancing:AddTags", + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:CreateTargetGroup", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:DeleteRule", + "elasticloadbalancing:DeleteTargetGroup", + "elasticloadbalancing:DeregisterTargets", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeTags", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:ModifyRule", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:RemoveListenerCertificates", + "elasticloadbalancing:RemoveTags", + "elasticloadbalancing:SetIpAddressType", + "elasticloadbalancing:SetSecurityGroups", + "elasticloadbalancing:SetSubnets", + "elasticloadbalancing:SetWebACL", + "iam:CreateServiceLinkedRole", + "iam:GetServerCertificate", + "iam:ListServerCertificates", + "waf-regional:GetWebACLForResource", + "waf-regional:GetWebACL", + "waf-regional:AssociateWebACL", + "waf-regional:DisassociateWebACL", + "tag:GetResources", + "tag:TagResources", + "waf:GetWebACL", + })) + }) + + }) + Context("NodeGroupEBS", func() { cfg, ng := newClusterConfigAndNodegroup(true) diff --git a/pkg/cfn/builder/iam.go b/pkg/cfn/builder/iam.go index e18a02cfca..ccf0f7da8b 100644 --- a/pkg/cfn/builder/iam.go +++ b/pkg/cfn/builder/iam.go @@ -236,6 +236,77 @@ func (n *NodeGroupResourceSet) addResourcesForIAM() { ) } + if v := n.spec.IAM.WithAddonPolicies.ALBIngress; v != nil && *v { + n.rs.attachAllowPolicy("PolicyALBIngress", refIR, "*", + []string{ + "acm:DescribeCertificate", + "acm:ListCertificates", + "acm:GetCertificate", + "ec2:AuthorizeSecurityGroupIngress", + "ec2:CreateSecurityGroup", + "ec2:CreateTags", + "ec2:DeleteTags", + "ec2:DeleteSecurityGroup", + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeInstances", + "ec2:DescribeInstanceStatus", + "ec2:DescribeInternetGateways", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeTags", + "ec2:DescribeVpcs", + "ec2:ModifyInstanceAttribute", + "ec2:ModifyNetworkInterfaceAttribute", + "ec2:RevokeSecurityGroupIngress", + "elasticloadbalancing:AddListenerCertificates", + "elasticloadbalancing:AddTags", + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:CreateTargetGroup", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:DeleteRule", + "elasticloadbalancing:DeleteTargetGroup", + "elasticloadbalancing:DeregisterTargets", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeTags", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:ModifyRule", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:RemoveListenerCertificates", + "elasticloadbalancing:RemoveTags", + "elasticloadbalancing:SetIpAddressType", + "elasticloadbalancing:SetSecurityGroups", + "elasticloadbalancing:SetSubnets", + "elasticloadbalancing:SetWebACL", + "iam:CreateServiceLinkedRole", + "iam:GetServerCertificate", + "iam:ListServerCertificates", + "waf-regional:GetWebACLForResource", + "waf-regional:GetWebACL", + "waf-regional:AssociateWebACL", + "waf-regional:DisassociateWebACL", + "tag:GetResources", + "tag:TagResources", + "waf:GetWebACL", + }, + ) + } + n.rs.defineOutputFromAtt(outputs.NodeGroupInstanceProfileARN, "NodeInstanceProfile.Arn", true, func(v string) error { n.spec.IAM.InstanceProfileARN = v return nil diff --git a/pkg/ctl/cmdutils/nodegroup_filter_test.go b/pkg/ctl/cmdutils/nodegroup_filter_test.go index 508b7d8c71..e429dc54fa 100644 --- a/pkg/ctl/cmdutils/nodegroup_filter_test.go +++ b/pkg/ctl/cmdutils/nodegroup_filter_test.go @@ -214,7 +214,8 @@ const expected = ` "autoScaler": false, "externalDNS": false, "appMesh": false, - "ebs": false + "ebs": false, + "albIngress": false } } }, @@ -244,7 +245,8 @@ const expected = ` "autoScaler": false, "externalDNS": false, "appMesh": false, - "ebs": false + "ebs": false, + "albIngress": false } } }, @@ -272,7 +274,8 @@ const expected = ` "autoScaler": false, "externalDNS": false, "appMesh": false, - "ebs": false + "ebs": false, + "albIngress": false } }, "clusterDNS": "1.2.3.4" @@ -301,7 +304,8 @@ const expected = ` "autoScaler": false, "externalDNS": false, "appMesh": false, - "ebs": false + "ebs": false, + "albIngress": false } } }, @@ -332,7 +336,8 @@ const expected = ` "autoScaler": false, "externalDNS": false, "appMesh": false, - "ebs": false + "ebs": false, + "albIngress": false } }, "clusterDNS": "4.2.8.14" @@ -364,7 +369,8 @@ const expected = ` "autoScaler": false, "externalDNS": false, "appMesh": false, - "ebs": false + "ebs": false, + "albIngress": false } } } diff --git a/pkg/ctl/cmdutils/nodegroup_flags.go b/pkg/ctl/cmdutils/nodegroup_flags.go index cd9b677752..3d19bd672e 100644 --- a/pkg/ctl/cmdutils/nodegroup_flags.go +++ b/pkg/ctl/cmdutils/nodegroup_flags.go @@ -56,8 +56,10 @@ func AddCommonCreateNodeGroupIAMAddonsFlags(fs *pflag.FlagSet, ng *api.NodeGroup ng.IAM.WithAddonPolicies.ExternalDNS = new(bool) ng.IAM.WithAddonPolicies.ImageBuilder = new(bool) ng.IAM.WithAddonPolicies.AppMesh = new(bool) + ng.IAM.WithAddonPolicies.ALBIngress = new(bool) fs.BoolVar(ng.IAM.WithAddonPolicies.AutoScaler, "asg-access", false, "enable IAM policy for cluster-autoscaler") fs.BoolVar(ng.IAM.WithAddonPolicies.ExternalDNS, "external-dns-access", false, "enable IAM policy for external-dns") fs.BoolVar(ng.IAM.WithAddonPolicies.ImageBuilder, "full-ecr-access", false, "enable full access to ECR") fs.BoolVar(ng.IAM.WithAddonPolicies.AppMesh, "appmesh-access", false, "enable full access to AppMesh") + fs.BoolVar(ng.IAM.WithAddonPolicies.ALBIngress, "alb-ingress-access", false, "enable full access for alb-ingress-controller") }