Skip to main content

Required IAM Policies

Palette requires proper Amazon Web Services (AWS) permissions to operate and perform actions on your behalf. You must grant these permissions to the Identity and Access Management (IAM) User or Role that you use to connect your AWS account to Palette.

There are two options for granting permissions to Palette. You can use the Core IAM Policies or the Minimum Permissions Policies:

  • The Core IAM policies are a set of AWS-managed and customer-managed policies that grant broader permissions for Palette to operate. Using these policies reduces the prerequisites required compared to the minimum permissions policies.

  • The Minimum Permissions policies are a set of customer-managed policies that are designed to follow the principle of least privilege. Use the dynamic policy to allow Palette to operate and create Virtual Private Cloud (VPC) resources as needed, or the static policy to deploy clusters within an existing VPC without provisioning or deleting foundational network resources.

warning

You can attach a maximum of ten managed policies to an IAM User or Role. Exceeding this limit results in cluster deployment failures. If you have to exceed the limit, consider combining policies into a custom-managed policy. You can learn more about AWS IAM limits in the IAM Quotas reference guide.

You can use Palette CLI to verify you have setup the correct permissions. Check out the Palette CLI validate-auth command section for more information.

Core IAM Policies

The following core IAM policies include all the permissions needed for Palette to deploy and manage clusters on AWS:

  • PaletteControllerPolicy
  • PaletteControlPlanePolicy
  • PaletteNodesPolicy
  • PaletteDeploymentPolicy

If you want to deploy AWS Elastic Kubernetes Service (EKS) clusters, make sure to also attach the PaletteControllersEKSPolicy on top of the core policies. Check out the Controllers EKS Policy section to review the IAM policy.

Additional IAM policies may be required depending on the use case. Check out the Additional IAM Policies for Specific Use Cases section for more information.

Last Update: December 9, 2025

{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iam:DeleteOpenIDConnectProvider",
"iam:GetOpenIDConnectProvider",
"iam:ListOpenIDConnectProviders",
"iam:TagOpenIDConnectProvider",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeInstanceRefreshes",
"ec2:AllocateAddress",
"ec2:AssociateRouteTable",
"ec2:AttachInternetGateway",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateInternetGateway",
"ec2:CreateLaunchTemplate",
"ec2:CreateLaunchTemplateVersion",
"ec2:CreateNatGateway",
"ec2:CreateRoute",
"ec2:CreateRouteTable",
"ec2:CreateSecurityGroup",
"ec2:CreateSubnet",
"ec2:CreateTags",
"ec2:CreateVpc",
"ec2:DeleteInternetGateway",
"ec2:DeleteLaunchTemplate",
"ec2:DeleteLaunchTemplateVersions",
"ec2:DeleteNatGateway",
"ec2:DeleteRouteTable",
"ec2:DeleteSecurityGroup",
"ec2:DeleteSubnet",
"ec2:DeleteTags",
"ec2:DeleteVpc",
"ec2:DescribeAccountAttributes",
"ec2:DescribeAddresses",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeInternetGateways",
"ec2:DescribeKeyPairs",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeNatGateways",
"ec2:DescribeNetworkInterfaceAttribute",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeVolumes",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcs",
"ec2:DetachInternetGateway",
"ec2:DisassociateAddress",
"ec2:DisassociateRouteTable",
"ec2:ModifyInstanceAttribute",
"ec2:ModifyNetworkInterfaceAttribute",
"ec2:ModifySubnetAttribute",
"ec2:ModifyVpcAttribute",
"ec2:ReleaseAddress",
"ec2:ReplaceRoute",
"ec2:RevokeSecurityGroupIngress",
"ec2:RunInstances",
"ec2:TerminateInstances",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
"elasticloadbalancing:ConfigureHealthCheck",
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DeleteTargetGroup",
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:RemoveTags",
"iam:CreateOpenIDConnectProvider",
"tag:GetResources",
"ec2:DescribeIpamPools",
"ec2:AllocateIpamPoolCidr",
"ec2:AttachNetworkInterface",
"ec2:DetachNetworkInterface",
"ec2:AssignIpv6Addresses",
"ec2:AssignPrivateIpAddresses",
"ec2:UnassignPrivateIpAddresses",
"ec2:AssociateVpcCidrBlock",
"ec2:CreateCarrierGateway",
"ec2:CreateEgressOnlyInternetGateway",
"ec2:CreateNetworkInterface",
"ec2:CreateVpcEndpoint",
"ec2:DisassociateVpcCidrBlock",
"ec2:ModifyVpcEndpoint",
"ec2:DeleteCarrierGateway",
"ec2:DeleteEgressOnlyInternetGateway",
"ec2:DeleteVpcEndpoints",
"ec2:DescribeCarrierGateways",
"ec2:DescribeInstanceTypes",
"ec2:DescribeEgressOnlyInternetGateways",
"ec2:DescribeVpcEndpoints",
"ec2:DescribeDhcpOptions",
"ec2:DescribeTags",
"ec2:GetInstanceMetadataDefaults",
"ec2:ModifyInstanceMetadataOptions",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:SetSecurityGroups",
"elasticloadbalancing:SetSubnets",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:CreateTargetGroup",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeleteListener",
"sts:AssumeRole"
],
"Resource": ["*"],
"Effect": "Allow"
},
{
"Action": [
"autoscaling:CreateAutoScalingGroup",
"autoscaling:UpdateAutoScalingGroup",
"autoscaling:CreateOrUpdateTags",
"autoscaling:StartInstanceRefresh",
"autoscaling:DeleteAutoScalingGroup",
"autoscaling:DeleteTags"
],
"Resource": [
"arn:*:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/*"
],
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"iam:AWSServiceName": "autoscaling.amazonaws.com"
}
},
"Action": ["iam:CreateServiceLinkedRole"],
"Resource": [
"arn:*:iam::*:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"
],
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"iam:AWSServiceName": "elasticloadbalancing.amazonaws.com"
}
},
"Action": ["iam:CreateServiceLinkedRole"],
"Resource": [
"arn:*:iam::*:role/aws-service-role/elasticloadbalancing.amazonaws.com/AWSServiceRoleForElasticLoadBalancing"
],
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"iam:AWSServiceName": "spot.amazonaws.com"
}
},
"Action": ["iam:CreateServiceLinkedRole"],
"Resource": [
"arn:*:iam::*:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot"
],
"Effect": "Allow"
},
{
"Action": ["iam:PassRole"],
"Resource": ["arn:*:iam::*:role/*.cluster-api-provider-aws.sigs.k8s.io"],
"Effect": "Allow"
},
{
"Action": [
"secretsmanager:CreateSecret",
"secretsmanager:DeleteSecret",
"secretsmanager:TagResource"
],
"Resource": ["arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/*"],
"Effect": "Allow"
},
{
"Action": [
"s3:DeleteObject",
"s3:PutBucketOwnershipControls",
"s3:PutBucketPolicy",
"s3:PutBucketPublicAccessBlock",
"s3:PutObjectAcl",
"s3:PutObject"
],
"Resource": ["arn:*:s3:::*"],
"Effect": "Allow"
}
]
}

Minimum Permissions Policies

The following policies are designed from the principle of least privilege. You can use these policies to narrow the permissions Palette requires to operate instead of using the Core IAM Policies.

After adding these policies to your IAM User or Role, you must also create the required CloudFormation stack for Palette manually in your AWS region. Finally, you must configure the Kubernetes layer of your cluster profiles to use the manually created CloudFormation stack.

info

If you want to use minimum permissions policies for deploying AWS Infrastructure as a Service (IaaS) clusters, you must use the Palette eXtended Kubernetes (PXK) pack for the Kubernetes layer of your cluster profiles.

This requirement exists because only the PXK pack supports the manageCloudFormationStackManually property required to reference a manually created CloudFormation stack.

Add Minimum Permissions Policies to IAM User or Role

Add at least one of the following policies to your IAM User or Role based on your use case:

  • Minimum IaaS Dynamic Permissions allows full lifecycle provisioning and management of Elastic Compute Cloud (EC2), VPC, and load balancing resources, with IAM access limited to passing Cluster API–managed roles and scoped Secrets Manager usage.

  • Minimum IaaS Static Permissions allows management of EC2 instances, security groups, and load balancers within existing VPC infrastructure, while restricting core network provisioning and limiting IAM access to Cluster API–managed roles with scoped Secrets Manager usage.

  • Minimum EKS Dynamic Permissions allows full lifecycle provisioning of EKS clusters and node groups, including required EC2 and VPC resources, with scoped IAM permissions for OpenID Connect (OIDC) provider management and Cluster API role usage to enable IAM Roles for Service Accounts (IRSA).

  • Minimum EKS Static Permissions allows management of EKS clusters and node groups within pre-existing EC2 and VPC infrastructure, with restricted network provisioning and scoped IAM permissions for OIDC provider management and Cluster API role usage to enable IRSA.

The following policy allows Palette to operate and create VPC resources as needed while retaining minimal permissions for deploying AWS IaaS clusters through Palette.

Last Update: February 14, 2026

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2Permissions",
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DeleteSubnet",
"ec2:DescribeAddresses",
"ec2:DescribeInstances",
"ec2:CreateNatGateway",
"ec2:DescribeRegions",
"ec2:CreateVpc",
"ec2:DescribeDhcpOptions",
"ec2:AttachInternetGateway",
"ec2:DescribeVpcAttribute",
"ec2:DeleteRouteTable",
"ec2:ModifySubnetAttribute",
"ec2:AssociateRouteTable",
"ec2:DescribeInternetGateways",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeAvailabilityZones",
"ec2:CreateRoute",
"ec2:CreateInternetGateway",
"ec2:CreateSecurityGroup",
"ec2:ModifyVpcAttribute",
"ec2:DescribeKeyPairs",
"ec2:DescribeRouteTables",
"ec2:ReleaseAddress",
"ec2:TerminateInstances",
"ec2:CreateTags",
"ec2:CreateRouteTable",
"ec2:RunInstances",
"ec2:DetachInternetGateway",
"ec2:DescribeNatGateways",
"ec2:DisassociateRouteTable",
"ec2:AllocateAddress",
"ec2:DescribeSecurityGroups",
"ec2:RevokeSecurityGroupIngress",
"ec2:DescribeImages",
"ec2:DescribeVpcs",
"ec2:DeleteSecurityGroup",
"ec2:DescribeInstanceTypes",
"ec2:DeleteNatGateway",
"ec2:DescribeVpcEndpoints",
"ec2:DeleteVpc",
"ec2:CreateSubnet",
"ec2:DescribeSubnets"
],
"Resource": "*"
},
{
"Sid": "ELBPermissions",
"Effect": "Allow",
"Action": [
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:ConfigureHealthCheck",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
"elasticloadbalancing:ModifyLoadBalancerAttributes"
],
"Resource": "*"
},
{
"Sid": "IAMPassRole",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": [
"arn:*:iam::*:role/*.cluster-api-provider-aws.sigs.k8s.io"
]
},
{
"Sid": "SecretsManagerPermissions",
"Effect": "Allow",
"Action": [
"secretsmanager:CreateSecret",
"secretsmanager:DeleteSecret",
"secretsmanager:TagResource"
],
"Resource": [
"arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/*"
]
}
]
}
warning

The following are important points to be aware of.

  • These permissions specified do not include all the permissions required for all possible use cases and for taking full advantage of all Palette features. Additional permissions may be required based on the specific use case. Review the Additional IAM Policies for Specific Use Cases section for more information.

  • These IAM policies cannot be used as an inline policy, as it exceeds the 2048 non-whitespace character limit by AWS. Break policy into multiple inline policies or create new managed policies.

  • The following IAM warning is expected and can be ignored:

    These policies define some actions, resources, or conditions that do not provide permissions. To grant access, policies must have an action that has an applicable resource or condition.

Create CloudFormation Stacks for Palette

When using the minimum permissions policies, you must manually create the CloudFormation stack that Palette uses to create the required Cluster API Provider AWS (CAPA) roles. This is not required when using the core policies, as the stack is created automatically using the more permissive policies.

  1. Create a file named palette-cloudformation-input-template.yaml and copy the contents of the following CloudFormation template. This template is used for creating the required CAPA roles.

    Last Update: February 14, 2026

    AWSTemplateFormatVersion: 2010-09-09
    Resources:
    AWSIAMInstanceProfileControlPlane:
    Properties:
    InstanceProfileName: control-plane.cluster-api-provider-aws.sigs.k8s.io
    Roles:
    - Ref: AWSIAMRoleControlPlane
    Type: AWS::IAM::InstanceProfile
    AWSIAMInstanceProfileControllers:
    Properties:
    InstanceProfileName: controllers.cluster-api-provider-aws.sigs.k8s.io
    Roles:
    - Ref: AWSIAMRoleControllers
    Type: AWS::IAM::InstanceProfile
    AWSIAMInstanceProfileNodes:
    Properties:
    InstanceProfileName: nodes.cluster-api-provider-aws.sigs.k8s.io
    Roles:
    - Ref: AWSIAMRoleNodes
    Type: AWS::IAM::InstanceProfile
    AWSIAMManagedPolicyCloudProviderControlPlane:
    Properties:
    Description: For the Kubernetes Cloud Provider AWS Control Plane
    ManagedPolicyName: control-plane.cluster-api-provider-aws.sigs.k8s.io
    PolicyDocument:
    Statement:
    - Action:
    - autoscaling:DescribeAutoScalingGroups
    - autoscaling:DescribeLaunchConfigurations
    - autoscaling:DescribeTags
    - ec2:AssignIpv6Addresses
    - ec2:DescribeInstances
    - ec2:DescribeImages
    - ec2:DescribeRegions
    - ec2:DescribeRouteTables
    - ec2:DescribeSecurityGroups
    - ec2:DescribeSubnets
    - ec2:DescribeVolumes
    - ec2:CreateSecurityGroup
    - ec2:CreateTags
    - ec2:CreateVolume
    - ec2:ModifyInstanceAttribute
    - ec2:ModifyVolume
    - ec2:AttachVolume
    - ec2:AuthorizeSecurityGroupIngress
    - ec2:CreateRoute
    - ec2:DeleteRoute
    - ec2:DeleteSecurityGroup
    - ec2:DeleteVolume
    - ec2:DetachVolume
    - ec2:RevokeSecurityGroupIngress
    - ec2:DescribeVpcs
    - elasticloadbalancing:AddTags
    - elasticloadbalancing:AttachLoadBalancerToSubnets
    - elasticloadbalancing:ApplySecurityGroupsToLoadBalancer
    - elasticloadbalancing:CreateLoadBalancer
    - elasticloadbalancing:CreateLoadBalancerPolicy
    - elasticloadbalancing:CreateLoadBalancerListeners
    - elasticloadbalancing:ConfigureHealthCheck
    - elasticloadbalancing:DeleteLoadBalancer
    - elasticloadbalancing:DeleteLoadBalancerListeners
    - elasticloadbalancing:DescribeLoadBalancers
    - elasticloadbalancing:DescribeLoadBalancerAttributes
    - elasticloadbalancing:DetachLoadBalancerFromSubnets
    - elasticloadbalancing:DeregisterInstancesFromLoadBalancer
    - elasticloadbalancing:ModifyLoadBalancerAttributes
    - elasticloadbalancing:RegisterInstancesWithLoadBalancer
    - elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer
    - elasticloadbalancing:CreateListener
    - elasticloadbalancing:CreateTargetGroup
    - elasticloadbalancing:DeleteListener
    - elasticloadbalancing:DeleteTargetGroup
    - elasticloadbalancing:DeregisterTargets
    - elasticloadbalancing:DescribeListeners
    - elasticloadbalancing:DescribeLoadBalancerPolicies
    - elasticloadbalancing:DescribeTargetGroups
    - elasticloadbalancing:DescribeTargetHealth
    - elasticloadbalancing:ModifyListener
    - elasticloadbalancing:ModifyTargetGroup
    - elasticloadbalancing:RegisterTargets
    - elasticloadbalancing:SetLoadBalancerPoliciesOfListener
    - iam:CreateServiceLinkedRole
    - kms:DescribeKey
    Effect: Allow
    Resource:
    - '*'
    Version: 2012-10-17
    Roles:
    - Ref: AWSIAMRoleControlPlane
    Type: AWS::IAM::ManagedPolicy
    AWSIAMManagedPolicyCloudProviderNodes:
    Properties:
    Description: For the Kubernetes Cloud Provider AWS nodes
    ManagedPolicyName: nodes.cluster-api-provider-aws.sigs.k8s.io
    PolicyDocument:
    Statement:
    - Action:
    - ec2:AssignIpv6Addresses
    - ec2:DescribeInstances
    - ec2:DescribeRegions
    - ec2:CreateTags
    - ec2:DescribeTags
    - ec2:DescribeNetworkInterfaces
    - ec2:DescribeInstanceTypes
    - ecr:GetAuthorizationToken
    - ecr:BatchCheckLayerAvailability
    - ecr:GetDownloadUrlForLayer
    - ecr:GetRepositoryPolicy
    - ecr:DescribeRepositories
    - ecr:ListImages
    - ecr:BatchGetImage
    Effect: Allow
    Resource:
    - '*'
    - Action:
    - secretsmanager:DeleteSecret
    - secretsmanager:GetSecretValue
    Effect: Allow
    Resource:
    - arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/*
    - Action:
    - ssm:UpdateInstanceInformation
    - ssmmessages:CreateControlChannel
    - ssmmessages:CreateDataChannel
    - ssmmessages:OpenControlChannel
    - ssmmessages:OpenDataChannel
    - s3:GetEncryptionConfiguration
    Effect: Allow
    Resource:
    - '*'
    Version: 2012-10-17
    Roles:
    - Ref: AWSIAMRoleControlPlane
    - Ref: AWSIAMRoleNodes
    Type: AWS::IAM::ManagedPolicy
    AWSIAMManagedPolicyControllers:
    Properties:
    Description: For the Kubernetes Cluster API Provider AWS Controllers
    ManagedPolicyName: controllers.cluster-api-provider-aws.sigs.k8s.io
    PolicyDocument:
    Statement:
    - Action:
    - ec2:AttachNetworkInterface
    - ec2:DetachNetworkInterface
    - ec2:AllocateAddress
    - ec2:AssignIpv6Addresses
    - ec2:AssignPrivateIpAddresses
    - ec2:UnassignPrivateIpAddresses
    - ec2:AssociateRouteTable
    - ec2:AttachInternetGateway
    - ec2:AuthorizeSecurityGroupIngress
    - ec2:CreateInternetGateway
    - ec2:CreateEgressOnlyInternetGateway
    - ec2:CreateNatGateway
    - ec2:CreateNetworkInterface
    - ec2:CreateRoute
    - ec2:CreateRouteTable
    - ec2:CreateSecurityGroup
    - ec2:CreateSubnet
    - ec2:CreateTags
    - ec2:CreateVpc
    - ec2:ModifyVpcAttribute
    - ec2:DeleteInternetGateway
    - ec2:DeleteEgressOnlyInternetGateway
    - ec2:DeleteNatGateway
    - ec2:DeleteRouteTable
    - ec2:ReplaceRoute
    - ec2:DeleteSecurityGroup
    - ec2:DeleteSubnet
    - ec2:DeleteTags
    - ec2:DeleteVpc
    - ec2:DescribeAccountAttributes
    - ec2:DescribeAddresses
    - ec2:DescribeAvailabilityZones
    - ec2:DescribeInstances
    - ec2:DescribeInstanceTypes
    - ec2:DescribeInternetGateways
    - ec2:DescribeEgressOnlyInternetGateways
    - ec2:DescribeInstanceTypes
    - ec2:DescribeImages
    - ec2:DescribeNatGateways
    - ec2:DescribeNetworkInterfaces
    - ec2:DescribeNetworkInterfaceAttribute
    - ec2:DescribeRouteTables
    - ec2:DescribeSecurityGroups
    - ec2:DescribeSubnets
    - ec2:DescribeVpcs
    - ec2:DescribeVpcAttribute
    - ec2:DescribeVolumes
    - ec2:DescribeTags
    - ec2:DetachInternetGateway
    - ec2:DisassociateRouteTable
    - ec2:DisassociateAddress
    - ec2:ModifyInstanceAttribute
    - ec2:ModifyNetworkInterfaceAttribute
    - ec2:ModifySubnetAttribute
    - ec2:ReleaseAddress
    - ec2:RevokeSecurityGroupIngress
    - ec2:RunInstances
    - ec2:TerminateInstances
    - tag:GetResources
    - elasticloadbalancing:AddTags
    - elasticloadbalancing:CreateLoadBalancer
    - elasticloadbalancing:ConfigureHealthCheck
    - elasticloadbalancing:DeleteLoadBalancer
    - elasticloadbalancing:DeleteTargetGroup
    - elasticloadbalancing:DescribeLoadBalancers
    - elasticloadbalancing:DescribeLoadBalancerAttributes
    - elasticloadbalancing:DescribeTargetGroups
    - elasticloadbalancing:ApplySecurityGroupsToLoadBalancer
    - elasticloadbalancing:DescribeTags
    - elasticloadbalancing:ModifyLoadBalancerAttributes
    - elasticloadbalancing:RegisterInstancesWithLoadBalancer
    - elasticloadbalancing:DeregisterInstancesFromLoadBalancer
    - elasticloadbalancing:RemoveTags
    - autoscaling:DescribeAutoScalingGroups
    - autoscaling:DescribeInstanceRefreshes
    - ec2:CreateLaunchTemplate
    - ec2:CreateLaunchTemplateVersion
    - ec2:DescribeLaunchTemplates
    - ec2:DescribeLaunchTemplateVersions
    - ec2:DeleteLaunchTemplate
    - ec2:DeleteLaunchTemplateVersions
    - ec2:DescribeKeyPairs
    - ec2:ModifyInstanceMetadataOptions
    Effect: Allow
    Resource:
    - '*'
    - Action:
    - autoscaling:CreateAutoScalingGroup
    - autoscaling:UpdateAutoScalingGroup
    - autoscaling:CreateOrUpdateTags
    - autoscaling:StartInstanceRefresh
    - autoscaling:DeleteAutoScalingGroup
    - autoscaling:DeleteTags
    Effect: Allow
    Resource:
    - arn:*:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/*
    - Action:
    - iam:CreateServiceLinkedRole
    Condition:
    StringLike:
    iam:AWSServiceName: autoscaling.amazonaws.com
    Effect: Allow
    Resource:
    - arn:*:iam::*:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling
    - Action:
    - iam:CreateServiceLinkedRole
    Condition:
    StringLike:
    iam:AWSServiceName: elasticloadbalancing.amazonaws.com
    Effect: Allow
    Resource:
    - arn:*:iam::*:role/aws-service-role/elasticloadbalancing.amazonaws.com/AWSServiceRoleForElasticLoadBalancing
    - Action:
    - iam:CreateServiceLinkedRole
    Condition:
    StringLike:
    iam:AWSServiceName: spot.amazonaws.com
    Effect: Allow
    Resource:
    - arn:*:iam::*:role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot
    - Action:
    - iam:PassRole
    Effect: Allow
    Resource:
    - arn:*:iam::*:role/*.cluster-api-provider-aws.sigs.k8s.io
    - Action:
    - secretsmanager:CreateSecret
    - secretsmanager:DeleteSecret
    - secretsmanager:TagResource
    Effect: Allow
    Resource:
    - arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/*
    Version: 2012-10-17
    Roles:
    - Ref: AWSIAMRoleControllers
    - Ref: AWSIAMRoleControlPlane
    Type: AWS::IAM::ManagedPolicy
    AWSIAMManagedPolicyControllersEKS:
    Properties:
    Description: For the Kubernetes Cluster API Provider AWS Controllers
    ManagedPolicyName: controllers-eks.cluster-api-provider-aws.sigs.k8s.io
    PolicyDocument:
    Statement:
    - Action:
    - ssm:GetParameter
    Effect: Allow
    Resource:
    - arn:*:ssm:*:*:parameter/aws/service/eks/optimized-ami/*
    - Action:
    - iam:CreateServiceLinkedRole
    Condition:
    StringLike:
    iam:AWSServiceName: eks.amazonaws.com
    Effect: Allow
    Resource:
    - arn:*:iam::*:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS
    - Action:
    - iam:CreateServiceLinkedRole
    Condition:
    StringLike:
    iam:AWSServiceName: eks-nodegroup.amazonaws.com
    Effect: Allow
    Resource:
    - arn:*:iam::*:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup
    - Action:
    - iam:CreateServiceLinkedRole
    Condition:
    StringLike:
    iam:AWSServiceName: eks-fargate.amazonaws.com
    Effect: Allow
    Resource:
    - arn:aws:iam::*:role/aws-service-role/eks-fargate-pods.amazonaws.com/AWSServiceRoleForAmazonEKSForFargate
    - Action:
    - iam:ListOpenIDConnectProviders
    - iam:GetOpenIDConnectProvider
    - iam:CreateOpenIDConnectProvider
    - iam:AddClientIDToOpenIDConnectProvider
    - iam:UpdateOpenIDConnectProviderThumbprint
    - iam:DeleteOpenIDConnectProvider
    - iam:TagOpenIDConnectProvider
    Effect: Allow
    Resource:
    - '*'
    - Action:
    - iam:GetRole
    - iam:ListAttachedRolePolicies
    Effect: Allow
    Resource:
    - arn:*:iam::*:role/*
    - Action:
    - iam:GetPolicy
    Effect: Allow
    Resource:
    - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
    - Action:
    - eks:DescribeCluster
    - eks:ListClusters
    - eks:CreateCluster
    - eks:TagResource
    - eks:UpdateClusterVersion
    - eks:DeleteCluster
    - eks:UpdateClusterConfig
    - eks:UntagResource
    - eks:UpdateNodegroupVersion
    - eks:DescribeNodegroup
    - eks:DeleteNodegroup
    - eks:UpdateNodegroupConfig
    - eks:CreateNodegroup
    - eks:AssociateEncryptionConfig
    - eks:ListIdentityProviderConfigs
    - eks:AssociateIdentityProviderConfig
    - eks:DescribeIdentityProviderConfig
    - eks:DisassociateIdentityProviderConfig
    Effect: Allow
    Resource:
    - arn:*:eks:*:*:cluster/*
    - arn:*:eks:*:*:nodegroup/*/*/*
    - Action:
    - ec2:AssociateVpcCidrBlock
    - ec2:DisassociateVpcCidrBlock
    - eks:ListAddons
    - eks:CreateAddon
    - eks:DescribeAddonVersions
    - eks:DescribeAddon
    - eks:DeleteAddon
    - eks:UpdateAddon
    - eks:TagResource
    - eks:DescribeFargateProfile
    - eks:CreateFargateProfile
    - eks:DeleteFargateProfile
    Effect: Allow
    Resource:
    - '*'
    - Action:
    - iam:PassRole
    Condition:
    StringEquals:
    iam:PassedToService: eks.amazonaws.com
    Effect: Allow
    Resource:
    - '*'
    - Action:
    - kms:CreateGrant
    - kms:DescribeKey
    Condition:
    ForAnyValue:StringLike:
    kms:ResourceAliases: alias/cluster-api-provider-aws-*
    Effect: Allow
    Resource:
    - '*'
    Version: 2012-10-17
    Roles:
    - Ref: AWSIAMRoleControllers
    - Ref: AWSIAMRoleControlPlane
    Type: AWS::IAM::ManagedPolicy
    AWSIAMRoleControlPlane:
    Properties:
    AssumeRolePolicyDocument:
    Statement:
    - Action:
    - sts:AssumeRole
    Effect: Allow
    Principal:
    Service:
    - ec2.amazonaws.com
    Version: 2012-10-17
    RoleName: control-plane.cluster-api-provider-aws.sigs.k8s.io
    Type: AWS::IAM::Role
    AWSIAMRoleControllers:
    Properties:
    AssumeRolePolicyDocument:
    Statement:
    - Action:
    - sts:AssumeRole
    Effect: Allow
    Principal:
    Service:
    - ec2.amazonaws.com
    Version: 2012-10-17
    RoleName: controllers.cluster-api-provider-aws.sigs.k8s.io
    Type: AWS::IAM::Role
    AWSIAMRoleEKSControlPlane:
    Properties:
    AssumeRolePolicyDocument:
    Statement:
    - Action:
    - sts:AssumeRole
    Effect: Allow
    Principal:
    Service:
    - eks.amazonaws.com
    Version: 2012-10-17
    ManagedPolicyArns:
    - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
    RoleName: eks-controlplane.cluster-api-provider-aws.sigs.k8s.io
    Type: AWS::IAM::Role
    AWSIAMRoleNodes:
    Properties:
    AssumeRolePolicyDocument:
    Statement:
    - Action:
    - sts:AssumeRole
    Effect: Allow
    Principal:
    Service:
    - ec2.amazonaws.com
    Version: 2012-10-17
    ManagedPolicyArns:
    - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
    - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
    RoleName: nodes.cluster-api-provider-aws.sigs.k8s.io
    Type: AWS::IAM::Role
  2. Once the file is created, use the following steps in the AWS Console or AWS CLI to create the CloudFormation stack.

    1. Log in to the AWS Management Console and navigate to the CloudFormation service.

    2. Create a new stack by clicking on the Create stack button and selecting With new resources (standard).

    3. Leave the Choose an existing template option selected, and under the Specify template section, select Upload a template file. Click Choose file and select the palette-cloudformation-input-template.yaml file you created earlier. Click Next.

    4. Provide the Stack name as cluster-api-provider-aws-sigs-k8s-io and click Next.

    5. On the Configure stack options page, check the box for I acknowledge that AWS CloudFormation might create IAM resources with customized names.

      Configure any additional options as needed and click Next.

    6. Review the stack configuration and click Submit to create the CloudFormation stack.

    7. Wait for the stack creation to complete. You can monitor the progress in the CloudFormation console.

Enable Manual CloudFormation Stack Management

After creating the CloudFormation stack, you must configure the Kubernetes layer of your cluster profiles to use the manually created stack. This ensures that Palette uses the existing stack rather than attempting to create and manage one automatically, which is not supported when using minimum permissions policies.

info

Only the Palette eXtended Kubernetes (PXK) pack supports the manageCloudFormationStackManually configuration.

  1. Log in to Palette.

  2. From the left main menu, select Profiles..

  3. Choose an existing cluster profile or create a new cluster profile.

  4. Once in the cluster profile overview with all the layers listed, select the Kubernetes layer to view the Edit Pack page.

  5. In the YAML editor, add the manageCloudFormationStackManually.enabled field and set the value to true as shown below.

    pack:
    ---
    kubeadmconfig:
    ---
    manageCloudFormationStackManually:
    enabled: true
  6. Confirm Updates to save the changes to the Kubernetes layer.

  7. Save Changes to the cluster profile.

Additional IAM Policies for Specific Use Cases

Controllers EKS Policy

If you plan to deploy AWS EKS host clusters, make sure to attach the PaletteControllersEKSPolicy on top of the Core IAM. If you are using the minimum permissions policies for EKS (static or dynamic), this is not required.

Last Update: May 25, 2025

{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["ssm:GetParameter"],
"Resource": ["arn:*:ssm:*:*:parameter/aws/service/eks/optimized-ami/*"],
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"iam:AWSServiceName": "eks.amazonaws.com"
}
},
"Action": ["iam:CreateServiceLinkedRole"],
"Resource": [
"arn:*:iam::*:role/aws-service-role/eks.amazonaws.com/AWSServiceRoleForAmazonEKS"
],
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"iam:AWSServiceName": "eks-nodegroup.amazonaws.com"
}
},
"Action": ["iam:CreateServiceLinkedRole"],
"Resource": [
"arn:*:iam::*:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup"
],
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"iam:AWSServiceName": "eks-fargate.amazonaws.com"
}
},
"Action": ["iam:CreateServiceLinkedRole"],
"Resource": [
"arn:*:iam::*:role/aws-service-role/eks-fargate-pods.amazonaws.com/AWSServiceRoleForAmazonEKSForFargate"
],
"Effect": "Allow"
},
{
"Action": [
"iam:AddClientIDToOpenIDConnectProvider",
"iam:CreateOpenIDConnectProvider",
"iam:DeleteOpenIDConnectProvider",
"iam:ListOpenIDConnectProviders",
"iam:UpdateOpenIDConnectProviderThumbprint",
"iam:GetOpenIDConnectProvider"
],
"Resource": ["*"],
"Effect": "Allow"
},
{
"Action": [
"iam:GetRole",
"iam:ListAttachedRolePolicies",
"iam:DetachRolePolicy",
"iam:DeleteRole",
"iam:CreateRole",
"iam:TagRole",
"iam:UntagRole",
"iam:AttachRolePolicy"
],
"Resource": ["arn:*:iam::*:role/*"],
"Effect": "Allow"
},
{
"Action": ["iam:GetPolicy"],
"Resource": ["arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"],
"Effect": "Allow"
},
{
"Action": [
"eks:DescribeCluster",
"eks:ListClusters",
"eks:CreateCluster",
"eks:TagResource",
"eks:UpdateClusterVersion",
"eks:DeleteCluster",
"eks:UpdateClusterConfig",
"eks:UntagResource",
"eks:UpdateNodegroupVersion",
"eks:DescribeNodegroup",
"eks:DeleteNodegroup",
"eks:UpdateNodegroupConfig",
"eks:CreateNodegroup",
"eks:AssociateEncryptionConfig",
"eks:ListIdentityProviderConfigs",
"eks:AssociateIdentityProviderConfig",
"eks:DescribeIdentityProviderConfig",
"eks:DisassociateIdentityProviderConfig"
],
"Resource": ["arn:*:eks:*:*:cluster/*", "arn:*:eks:*:*:nodegroup/*/*/*"],
"Effect": "Allow"
},
{
"Action": [
"ec2:AssociateVpcCidrBlock",
"ec2:DisassociateVpcCidrBlock",
"eks:ListAddons",
"eks:CreateAddon",
"eks:DescribeAddonVersions",
"eks:DescribeAddon",
"eks:DeleteAddon",
"eks:UpdateAddon",
"eks:TagResource",
"eks:DescribeFargateProfile",
"eks:CreateFargateProfile",
"eks:DeleteFargateProfile"
],
"Resource": ["*"],
"Effect": "Allow"
},
{
"Condition": {
"StringEquals": {
"iam:PassedToService": "eks.amazonaws.com"
}
},
"Action": ["iam:PassRole"],
"Resource": ["*"],
"Effect": "Allow"
},
{
"Condition": {
"ForAnyValue:StringLike": {
"kms:ResourceAliases": "alias/cluster-api-provider-aws-*"
}
},
"Action": ["kms:CreateGrant", "kms:DescribeKey"],
"Resource": ["*"],
"Effect": "Allow"
}
]
}

Host Resource Groups Policy

If you plan to deploy AWS IaaS clusters on Amazon EC2 Dedicated Hosts, you must attach the PaletteHostResourceGroupsPolicy on top of the Core IAM or Minimum Permissions policies.

Last Update: January 17, 2026

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PaletteHostResourceGroupsPermissions",
"Effect": "Allow",
"Action": [
"resource-groups:ListGroups",
"resource-groups:GetGroupConfiguration",
"resource-groups:ListGroupResources",
"license-manager:GetLicenseConfiguration",
"ec2:DescribeHosts"
],
"Resource": "*"
}
]
}

Global Role Additional Policies

There may be situations where additional node-level policies must be added to your deployment. For instance, when you create a host cluster with the AWS EBS CSI storage layer, ensure AmazonEBSCSIDriverPolicy is included. This is not required when using minimum permissions policies.

To add additional node-level policies:

  1. Log in to Palette.
  2. Switch to the Tenant Admin project, and click on the Tenant Settings on the main menu.
  3. Click on Cloud Accounts.
  4. Add an AWS account if one does not exist.
  5. After validation of the AWS credentials, ensure Add IAM policies are enabled. You can specify additional Amazon Resource Names (ARNs) to be attached. The attached policies will be included to all the clusters launched with this specific AWS cloud Account.

AmazonEBSCSIDriverPolicy:

Last Update: November 8, 2023

roleName: "custom-ng-role"
roleAdditionalPolicies:
- "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy"

Roles and Policies

Palette creates and attaches IAM roles and policies to the clusters it deploys. Depending on which type of cluster you deploy, either AWS EKS or IaaS (using EC2 instances), Palette creates and attaches different IAM roles and policies.

Select the tab below to review the IAM roles and policies attached to the cluster's IAM role and the node group's IAM role.

When you deploy an EKS cluster using Palette, two IAM roles are created automatically. One IAM role is for the cluster, and the other IAM role for the worker node group.

The cluster's IAM role is named in the following syntax, [cluster-name]-iam-service-role, and the node group's IAM role is named as ng-role_worker-pool-[random-string]. These two IAM roles have customer-managed and AWS-managed IAM policies. You can attach more IAM policies to any of these IAM roles if needed. The following table lists the IAM policies attached to the cluster's IAM role and the node group's IAM role.

Policy NameTypeAttached to the cluster's IAM role?Attached to the node group's IAM role?Description
AmazonEKSClusterPolicyAWS managedProvides the cluster permission to manage compute resources.
AmazonEC2ContainerRegistryReadOnlyAWS managedProvides the node group permission to pull images from Amazon ECR.
AmazonEKS_CNI_PolicyAWS managedProvides the node group permission to manage network resources.
AmazonEKSWorkerNodePolicyAWS managedThis policy allows Amazon EKS worker nodes to connect to Amazon EKS Clusters.
AmazonSSMManagedInstanceCoreAWS managedThe policy for Amazon EC2 Role to enable AWS Systems Manager service core functionality.

In addition to the policies listed above, if you specified other IAM policies during the AWS account registration, those policies are also attached to the cluster's IAM role and the node group's IAM role.

warning

Be aware that AWS has a default limit of 10 policies per role. If you exceed this limit, the cluster deployment may fail due to the IAM role policy limit. Request a service quota increase for the AWS account to increase the limit.