diff --git a/pkg/apis/eksctl.io/v1alpha5/assets/schema.json b/pkg/apis/eksctl.io/v1alpha5/assets/schema.json index d3f97692a3..e9529387d7 100755 --- a/pkg/apis/eksctl.io/v1alpha5/assets/schema.json +++ b/pkg/apis/eksctl.io/v1alpha5/assets/schema.json @@ -304,11 +304,17 @@ "$ref": "#/definitions/ARN", "description": "node role to use for nodes launched by Auto Mode.", "x-intellij-html-description": "node role to use for nodes launched by Auto Mode." + }, + "permissionsBoundaryARN": { + "$ref": "#/definitions/ARN", + "description": "permissions boundary to use when creating the Auto Mode node role.", + "x-intellij-html-description": "permissions boundary to use when creating the Auto Mode node role." } }, "preferredOrder": [ "enabled", "nodeRoleARN", + "permissionsBoundaryARN", "nodePools" ], "additionalProperties": false diff --git a/pkg/apis/eksctl.io/v1alpha5/auto_mode.go b/pkg/apis/eksctl.io/v1alpha5/auto_mode.go index 004e2796cc..efb229e68a 100644 --- a/pkg/apis/eksctl.io/v1alpha5/auto_mode.go +++ b/pkg/apis/eksctl.io/v1alpha5/auto_mode.go @@ -20,6 +20,8 @@ type AutoModeConfig struct { Enabled *bool `json:"enabled,omitempty"` // NodeRoleARN is the node role to use for nodes launched by Auto Mode. NodeRoleARN ARN `json:"nodeRoleARN,omitempty"` + // PermissionsBoundaryARN is the permissions boundary to use when creating the Auto Mode node role. + PermissionsBoundaryARN ARN `json:"permissionsBoundaryARN,omitempty"` // NodePools is a list of node pools to create. NodePools *[]string `json:"nodePools,omitempty"` } @@ -43,6 +45,12 @@ func ValidateAutoModeConfig(clusterConfig *ClusterConfig) error { if len(*autoModeConfig.NodePools) == 0 && !autoModeConfig.NodeRoleARN.IsZero() { return errors.New("cannot specify autoModeConfig.nodeRoleARN when autoModeConfig.nodePools is empty") } + if len(*autoModeConfig.NodePools) == 0 && !autoModeConfig.PermissionsBoundaryARN.IsZero() { + return errors.New("cannot specify autoModeConfig.permissionBoundaryARN when autoModeConfig.nodePools is empty") + } + if !autoModeConfig.NodeRoleARN.IsZero() && !autoModeConfig.PermissionsBoundaryARN.IsZero() { + return errors.New("cannot specify autoModeConfig.permissionBoundaryARN when autoModeConfig.nodeRoleARN is set") + } seenNodePools := map[string]struct{}{} for _, np := range *autoModeConfig.NodePools { if _, ok := seenNodePools[np]; ok { @@ -54,8 +62,8 @@ func ValidateAutoModeConfig(clusterConfig *ClusterConfig) error { seenNodePools[np] = struct{}{} } } - } else if !autoModeConfig.NodeRoleARN.IsZero() || autoModeConfig.HasNodePools() { - return errors.New("cannot set autoModeConfig.nodeRoleARN or autoModeConfig.nodePools when Auto Mode is disabled") + } else if !autoModeConfig.PermissionsBoundaryARN.IsZero() || !autoModeConfig.NodeRoleARN.IsZero() || autoModeConfig.HasNodePools() { + return errors.New("cannot set autoModeConfig.nodeRoleARN, autoModeConfig.permissionBoundaryARN, or autoModeConfig.nodePools when Auto Mode is disabled") } return nil } diff --git a/pkg/apis/eksctl.io/v1alpha5/auto_mode_validation_test.go b/pkg/apis/eksctl.io/v1alpha5/auto_mode_validation_test.go index 96ce303ae3..cb0fe8b9ee 100644 --- a/pkg/apis/eksctl.io/v1alpha5/auto_mode_validation_test.go +++ b/pkg/apis/eksctl.io/v1alpha5/auto_mode_validation_test.go @@ -42,5 +42,20 @@ var _ = DescribeTable("Auto Mode Validation", func(c *api.ClusterConfig, expecte NodeRoleARN: api.MustParseARN("arn:aws:iam::1234:role/CustomNodeRole"), NodePools: &[]string{api.AutoModeNodePoolGeneralPurpose}, }, - }, "cannot set autoModeConfig.nodeRoleARN or autoModeConfig.nodePools when Auto Mode is disabled"), + }, "cannot set autoModeConfig.nodeRoleARN, autoModeConfig.permissionBoundaryARN, or autoModeConfig.nodePools when Auto Mode is disabled"), + Entry("permissionsBoundary and nodePools specified when Auto Mode is disabled", &api.ClusterConfig{ + AutoModeConfig: &api.AutoModeConfig{ + Enabled: api.Disabled(), + PermissionsBoundaryARN: api.MustParseARN("arn:aws:iam::1234:policy/PermissionsBoundary"), + NodePools: &[]string{api.AutoModeNodePoolGeneralPurpose}, + }, + }, "cannot set autoModeConfig.nodeRoleARN, autoModeConfig.permissionBoundaryARN, or autoModeConfig.nodePools when Auto Mode is disabled"), + Entry("permissionsBoundary, nodeRoleARN, and nodePools specified", &api.ClusterConfig{ + AutoModeConfig: &api.AutoModeConfig{ + Enabled: api.Enabled(), + NodeRoleARN: api.MustParseARN("arn:aws:iam::1234:role/CustomNodeRole"), + PermissionsBoundaryARN: api.MustParseARN("arn:aws:iam::1234:policy/PermissionsBoundary"), + NodePools: &[]string{api.AutoModeNodePoolGeneralPurpose}, + }, + }, "cannot specify autoModeConfig.permissionBoundaryARN when autoModeConfig.nodeRoleARN is set"), ) diff --git a/pkg/cfn/builder/auto_mode.go b/pkg/cfn/builder/auto_mode.go index e7a7d526f4..832adab9a3 100644 --- a/pkg/cfn/builder/auto_mode.go +++ b/pkg/cfn/builder/auto_mode.go @@ -31,12 +31,15 @@ type AutoModeRefs struct { NodeRole *gfnt.Value } -func AddAutoModeResources(clusterTemplate *gfn.Template) (AutoModeRefs, error) { +func AddAutoModeResources(clusterTemplate *gfn.Template, permissionsBoundary string) (AutoModeRefs, error) { template, err := goformation.ParseYAML(autoModeNodeRoleTemplate) if err != nil { return AutoModeRefs{}, err } - for resourceName, resource := range template.Resources { + for resourceName, resource := range template.GetAllIAMRoleResources() { + if permissionsBoundary != "" { + resource.PermissionsBoundary = gfnt.NewString(permissionsBoundary) + } clusterTemplate.Resources[resourceName] = resource } for key, output := range template.Outputs { diff --git a/pkg/cfn/builder/cluster.go b/pkg/cfn/builder/cluster.go index 61917953a4..408126926a 100644 --- a/pkg/cfn/builder/cluster.go +++ b/pkg/cfn/builder/cluster.go @@ -338,7 +338,7 @@ func (c *ClusterResourceSet) addResourcesForControlPlane(subnetDetails *SubnetDe cluster.ComputeConfig = computeConfig if cc.NodeRoleARN.IsZero() { if cc.HasNodePools() { - autoModeRefs, err := AddAutoModeResources(c.rs.template) + autoModeRefs, err := AddAutoModeResources(c.rs.template, cc.PermissionsBoundaryARN.String()) if err != nil { return fmt.Errorf("error building cluster compute roles: %w", err) }