diff --git a/Makefile b/Makefile index 5f045584..92f1a541 100644 --- a/Makefile +++ b/Makefile @@ -75,6 +75,8 @@ IAMCTL_OUTPUT_DIR ?= ./pkg/controllers/awsloadbalancercontroller # Generated file name. IAMCTL_OUTPUT_FILE ?= iam_policy.go +IAMCTL_OUTPUT_STS_FILE ?= iam_policy_sts.go + # Go Package of the generated file. IAMCTL_GO_PACKAGE ?= awsloadbalancercontroller @@ -127,13 +129,26 @@ vet: ## Run go vet against code. .PHONY: iamctl-gen iamctl-gen: iamctl-build iam-gen - $(IAMCTL_BINARY) -i $(IAMCTL_ASSETS_DIR)/iam-policy.json -o $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_FILE) -p $(IAMCTL_GO_PACKAGE) -c $(IAMCTL_OUTPUT_CR_FILE) - go fmt -mod=vendor $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_FILE) - go vet -mod=vendor $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_FILE) + # controller's IAM policy as go code for non-STS clusters + @# inline policy is limited to 2048 (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html#reference_iam-quotas-entity-length) + $(IAMCTL_BINARY) -i $(IAMCTL_ASSETS_DIR)/iam-policy.json -o $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_FILE) -p $(IAMCTL_GO_PACKAGE) + + # controller's IAM policy as go code and as a CredentialsRequest yaml for STS clusters + @# role policy is limited to 10240 (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html#reference_iam-quotas-entity-length) + $(IAMCTL_BINARY) -i $(IAMCTL_ASSETS_DIR)/iam-policy.json -o $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_STS_FILE) -p $(IAMCTL_GO_PACKAGE) -f GetIAMPolicySTS -c $(IAMCTL_OUTPUT_CR_FILE) -n -s + go fmt -mod=vendor $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_FILE) $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_STS_FILE) + go vet -mod=vendor $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_FILE) $(IAMCTL_OUTPUT_DIR)/$(IAMCTL_OUTPUT_STS_FILE) + + # operator's IAM policy as go code for both non-STS and STS clusters + @# small enough to satisfy both cases $(IAMCTL_BINARY) -i $(IAMCTL_ASSETS_DIR)/operator-iam-policy.json -o ./pkg/operator/$(IAMCTL_OUTPUT_FILE) -p operator -n go fmt -mod=vendor ./pkg/operator/$(IAMCTL_OUTPUT_FILE) go vet -mod=vendor ./pkg/operator/$(IAMCTL_OUTPUT_FILE) +# The operator's CredentialsRequest is the source of truth for the operator's IAM policy. +# It's required to generate IAM role for STS clusters using ccoctl (docs/prerequisites.md#option-1-using-ccoctl). +# The below rule generates a corresponding AWS IAM policy JSON which can be used in AWS CLI commands (docs/prerequisites.md#option-2-using-the-aws-cli). +# The operator's IAM policy as go code is generated from the JSON policy and used in the operator to self provision credentials at startup. .PHONY: iam-gen iam-gen: ./hack/generate-iam-from-credrequest.sh ./hack/operator-credentials-request.yaml ./hack/operator-permission-policy.json diff --git a/assets/iam-policy.json b/assets/iam-policy.json index a8d47c8b..25293bfb 100644 --- a/assets/iam-policy.json +++ b/assets/iam-policy.json @@ -177,6 +177,28 @@ "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*" ] }, + { + "Effect": "Allow", + "Action": [ + "elasticloadbalancing:AddTags" + ], + "Resource": [ + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" + ], + "Condition": { + "StringEquals": { + "elasticloadbalancing:CreateAction": [ + "CreateTargetGroup", + "CreateLoadBalancer" + ] + }, + "Null": { + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + } + } + }, { "Effect": "Allow", "Action": [ diff --git a/hack/controller/controller-credentials-request.yaml b/hack/controller/controller-credentials-request.yaml index 4b7b2422..a62ced99 100644 --- a/hack/controller/controller-credentials-request.yaml +++ b/hack/controller/controller-credentials-request.yaml @@ -9,56 +9,208 @@ spec: kind: AWSProviderSpec statementEntries: - action: - - acm:DescribeCertificate - - acm:ListCertificates + - iam:CreateServiceLinkedRole + effect: Allow + resource: "*" + policyCondition: + "StringEquals": + "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com" + - action: + - ec2:DescribeAccountAttributes + - ec2:DescribeAddresses + - ec2:DescribeAvailabilityZones + - ec2:DescribeInternetGateways + - ec2:DescribeVpcs + - ec2:DescribeVpcPeeringConnections + - ec2:DescribeSubnets + - ec2:DescribeSecurityGroups + - ec2:DescribeInstances + - ec2:DescribeNetworkInterfaces + - ec2:DescribeTags + - ec2:GetCoipPoolUsage + - ec2:DescribeCoipPools + - elasticloadbalancing:DescribeLoadBalancers + - elasticloadbalancing:DescribeLoadBalancerAttributes + - elasticloadbalancing:DescribeListeners + - elasticloadbalancing:DescribeListenerCertificates + - elasticloadbalancing:DescribeSSLPolicies + - elasticloadbalancing:DescribeRules + - elasticloadbalancing:DescribeTargetGroups + - elasticloadbalancing:DescribeTargetGroupAttributes + - elasticloadbalancing:DescribeTargetHealth + - elasticloadbalancing:DescribeTags + effect: Allow + resource: "*" + - action: - cognito-idp:DescribeUserPoolClient + - acm:ListCertificates + - acm:DescribeCertificate + - iam:ListServerCertificates + - iam:GetServerCertificate + - waf-regional:GetWebACL + - waf-regional:GetWebACLForResource + - waf-regional:AssociateWebACL + - waf-regional:DisassociateWebACL + - wafv2:GetWebACL + - wafv2:GetWebACLForResource + - wafv2:AssociateWebACL + - wafv2:DisassociateWebACL + - shield:GetSubscriptionState + - shield:DescribeProtection + - shield:CreateProtection + - shield:DeleteProtection + effect: Allow + resource: "*" + - action: - ec2:AuthorizeSecurityGroupIngress + - ec2:RevokeSecurityGroupIngress + effect: Allow + resource: "*" + - action: - ec2:CreateSecurityGroup + effect: Allow + resource: "*" + - action: + - ec2:CreateTags + effect: Allow + resource: "arn:aws:ec2:*:*:security-group/*" + policyCondition: + "Null": + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + "StringEquals": + "ec2:CreateAction": "CreateSecurityGroup" + - action: - ec2:CreateTags - - ec2:DeleteSecurityGroup - ec2:DeleteTags - - ec2:Describe* - - ec2:GetCoipPoolUsage + effect: Allow + resource: "arn:aws:ec2:*:*:security-group/*" + policyCondition: + "Null": + "aws:RequestTag/elbv2.k8s.aws/cluster": "true" + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + - action: + - ec2:AuthorizeSecurityGroupIngress - ec2:RevokeSecurityGroupIngress - - elasticloadbalancing:AddListenerCertificates - - elasticloadbalancing:AddTags - - elasticloadbalancing:CreateListener + - ec2:DeleteSecurityGroup + effect: Allow + resource: "*" + policyCondition: + "Null": + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + - action: - elasticloadbalancing:CreateLoadBalancer - - elasticloadbalancing:CreateRule - elasticloadbalancing:CreateTargetGroup + effect: Allow + resource: "*" + policyCondition: + "Null": + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + - action: + - elasticloadbalancing:CreateListener - elasticloadbalancing:DeleteListener - - elasticloadbalancing:DeleteLoadBalancer + - elasticloadbalancing:CreateRule - elasticloadbalancing:DeleteRule - - elasticloadbalancing:DeleteTargetGroup - - elasticloadbalancing:DeregisterTargets - - elasticloadbalancing:Describe* - - elasticloadbalancing:ModifyListener - - elasticloadbalancing:ModifyLoadBalancerAttributes - - elasticloadbalancing:ModifyRule - - elasticloadbalancing:ModifyTargetGroup - - elasticloadbalancing:ModifyTargetGroupAttributes - - elasticloadbalancing:RegisterTargets - - elasticloadbalancing:RemoveListenerCertificates + effect: Allow + resource: "*" + - action: + - elasticloadbalancing:AddTags + - elasticloadbalancing:RemoveTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" + policyCondition: + "Null": + "aws:RequestTag/elbv2.k8s.aws/cluster": "true" + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + - action: + - elasticloadbalancing:AddTags + - elasticloadbalancing:RemoveTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*" + policyCondition: + "Null": + "aws:RequestTag/elbv2.k8s.aws/cluster": "true" + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + - action: + - elasticloadbalancing:AddTags + - elasticloadbalancing:RemoveTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" + policyCondition: + "Null": + "aws:RequestTag/elbv2.k8s.aws/cluster": "true" + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + - action: + - elasticloadbalancing:AddTags + - elasticloadbalancing:RemoveTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*" + - action: + - elasticloadbalancing:AddTags + - elasticloadbalancing:RemoveTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*" + - action: + - elasticloadbalancing:AddTags + - elasticloadbalancing:RemoveTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*" + - action: + - elasticloadbalancing:AddTags - elasticloadbalancing:RemoveTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*" + - action: + - elasticloadbalancing:AddTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" + policyCondition: + "Null": + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + "StringEquals": + "elasticloadbalancing:CreateAction": ["CreateTargetGroup","CreateLoadBalancer"] + - action: + - elasticloadbalancing:AddTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*" + policyCondition: + "Null": + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + "StringEquals": + "elasticloadbalancing:CreateAction": ["CreateTargetGroup","CreateLoadBalancer"] + - action: + - elasticloadbalancing:AddTags + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" + policyCondition: + "Null": + "aws:RequestTag/elbv2.k8s.aws/cluster": "false" + "StringEquals": + "elasticloadbalancing:CreateAction": ["CreateTargetGroup","CreateLoadBalancer"] + - action: + - elasticloadbalancing:ModifyLoadBalancerAttributes - elasticloadbalancing:SetIpAddressType - elasticloadbalancing:SetSecurityGroups - elasticloadbalancing:SetSubnets + - elasticloadbalancing:DeleteLoadBalancer + - elasticloadbalancing:ModifyTargetGroup + - elasticloadbalancing:ModifyTargetGroupAttributes + - elasticloadbalancing:DeleteTargetGroup + effect: Allow + resource: "*" + policyCondition: + "Null": + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" + - action: + - elasticloadbalancing:RegisterTargets + - elasticloadbalancing:DeregisterTargets + effect: Allow + resource: "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" + - action: - elasticloadbalancing:SetWebAcl - - iam:CreateServiceLinkedRole - - iam:GetServerCertificate - - iam:ListServerCertificates - - shield:CreateProtection - - shield:DeleteProtection - - shield:DescribeProtection - - shield:GetSubscriptionState - - waf-regional:AssociateWebACL - - waf-regional:DisassociateWebACL - - waf-regional:GetWebACL - - waf-regional:GetWebACLForResource - - wafv2:AssociateWebACL - - wafv2:DisassociateWebACL - - wafv2:GetWebACL - - wafv2:GetWebACLForResource + - elasticloadbalancing:ModifyListener + - elasticloadbalancing:AddListenerCertificates + - elasticloadbalancing:RemoveListenerCertificates + - elasticloadbalancing:ModifyRule effect: Allow resource: "*" secretRef: diff --git a/pkg/controllers/awsloadbalancercontroller/iam_policy_sts.go b/pkg/controllers/awsloadbalancercontroller/iam_policy_sts.go new file mode 100644 index 00000000..fc183da5 --- /dev/null +++ b/pkg/controllers/awsloadbalancercontroller/iam_policy_sts.go @@ -0,0 +1,323 @@ +package awsloadbalancercontroller + +import cco "github.com/openshift/cloud-credential-operator/pkg/apis/cloudcredential/v1" + +func GetIAMPolicySTS() IAMPolicy { + return IAMPolicy{ + Statement: []cco.StatementEntry{ + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{ + "StringEquals": cco.IAMPolicyConditionKeyValue{ + "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com", + }, + }, + Action: []string{ + "iam:CreateServiceLinkedRole", + }, + }, + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeInternetGateways", + "ec2:DescribeVpcs", + "ec2:DescribeVpcPeeringConnections", + "ec2:DescribeSubnets", + "ec2:DescribeSecurityGroups", + "ec2:DescribeInstances", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeTags", + "ec2:GetCoipPoolUsage", + "ec2:DescribeCoipPools", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:DescribeTags", + }, + }, + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "cognito-idp:DescribeUserPoolClient", + "acm:ListCertificates", + "acm:DescribeCertificate", + "iam:ListServerCertificates", + "iam:GetServerCertificate", + "waf-regional:GetWebACL", + "waf-regional:GetWebACLForResource", + "waf-regional:AssociateWebACL", + "waf-regional:DisassociateWebACL", + "wafv2:GetWebACL", + "wafv2:GetWebACLForResource", + "wafv2:AssociateWebACL", + "wafv2:DisassociateWebACL", + "shield:GetSubscriptionState", + "shield:DescribeProtection", + "shield:CreateProtection", + "shield:DeleteProtection", + }, + }, + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + }, + }, + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "ec2:CreateSecurityGroup", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:ec2:*:*:security-group/*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:RequestTag/elbv2.k8s.aws/cluster": "false", + }, + "StringEquals": cco.IAMPolicyConditionKeyValue{ + "ec2:CreateAction": "CreateSecurityGroup", + }, + }, + Action: []string{ + "ec2:CreateTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:ec2:*:*:security-group/*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false", + }, + }, + Action: []string{ + "ec2:CreateTags", + "ec2:DeleteTags", + }, + }, + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false", + }, + }, + Action: []string{ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress", + "ec2:DeleteSecurityGroup", + }, + }, + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:RequestTag/elbv2.k8s.aws/cluster": "false", + }, + }, + Action: []string{ + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateTargetGroup", + }, + }, + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:DeleteRule", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false", + }, + }, + Action: []string{ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false", + }, + }, + Action: []string{ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:RequestTag/elbv2.k8s.aws/cluster": "true", + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false", + }, + }, + Action: []string{ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:RequestTag/elbv2.k8s.aws/cluster": "false", + }, + "StringEquals": cco.IAMPolicyConditionKeyValue{ + "elasticloadbalancing:CreateAction": []string{"CreateTargetGroup", "CreateLoadBalancer"}, + }, + }, + Action: []string{ + "elasticloadbalancing:AddTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:RequestTag/elbv2.k8s.aws/cluster": "false", + }, + "StringEquals": cco.IAMPolicyConditionKeyValue{ + "elasticloadbalancing:CreateAction": []string{"CreateTargetGroup", "CreateLoadBalancer"}, + }, + }, + Action: []string{ + "elasticloadbalancing:AddTags", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:RequestTag/elbv2.k8s.aws/cluster": "false", + }, + "StringEquals": cco.IAMPolicyConditionKeyValue{ + "elasticloadbalancing:CreateAction": []string{"CreateTargetGroup", "CreateLoadBalancer"}, + }, + }, + Action: []string{ + "elasticloadbalancing:AddTags", + }, + }, + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{ + "Null": cco.IAMPolicyConditionKeyValue{ + "aws:ResourceTag/elbv2.k8s.aws/cluster": "false", + }, + }, + Action: []string{ + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:SetIpAddressType", + "elasticloadbalancing:SetSecurityGroups", + "elasticloadbalancing:SetSubnets", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:DeleteTargetGroup", + }, + }, + { + Effect: "Allow", + Resource: "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:DeregisterTargets", + }, + }, + { + Effect: "Allow", + Resource: "*", + PolicyCondition: cco.IAMPolicyCondition{}, + Action: []string{ + "elasticloadbalancing:SetWebAcl", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:AddListenerCertificates", + "elasticloadbalancing:RemoveListenerCertificates", + "elasticloadbalancing:ModifyRule", + }, + }, + }, + } +}