Prerequisites

Ensure that the following prerequisites are met before deploying the PPC.

Updating the Roles and Permissions using JSON

The roles and permissions are updated using the JSONs.

From the AWS Console, navigate to IAM > Policies > Create policy > JSON, and create the following JSONs.

Note: Before using the provided JSON, replace the AWS_ACCOUNT_ID and REGION values with those of the account and region where the resources are being deployed.

  1. Creating KMS key and S3 bucket.
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "ReadOnlyAccess",
			"Effect": "Allow",
			"Action": [
				"eks:DescribeClusterVersions",
				"ec2:DescribeInstances",
				"ec2:DescribeVolumes",
				"s3:ListAllMyBuckets",
				"iam:ListUsers",
				"ec2:RunInstances",
				"ec2:DescribeInstances",
				"ec2:DescribeVolumes",
				"ec2:CreateKeyPair",
				"ec2:DescribeImages"
			],
			"Resource": "*"
		},
		{
			"Sid": "ScopedS3AndKMS",
			"Effect": "Allow",
			"Action": [
				"s3:ListBucket",
				"s3:PutEncryptionConfiguration",
				"s3:GetEncryptionConfiguration",
				"kms:CreateKey",
				"kms:PutKeyPolicy",
				"kms:GetKeyPolicy"
			],
			"Resource": [
				"arn:aws:s3:::*",
				"arn:aws:kms:*:<AWS_ACCOUNT_ID>:key/*"
			]
		},
		{
			"Sid": "SelfServiceIAM",
			"Effect": "Allow",
			"Action": [
				"iam:ListSSHPublicKeys",
				"iam:ListServiceSpecificCredentials",
				"iam:GetLoginProfile",
				"iam:ListAccessKeys",
				"iam:CreateAccessKey"
			],
			"Resource": "arn:aws:iam::<AWS_ACCOUNT_ID>:user/${aws:username}"
		},
        {
			"Sid": "EC2KeyPairPermission",
			"Effect": "Allow",
			"Action": [
				"ec2:CreateKeyPair",
				"ec2:DescribeKeyPairs"
			],
			"Resource": [
				"*"
			]
		}
	]
}
  1. Creating EC2 Service Policy.
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "DenyEC2Instances",
			"Effect": "Deny",
			"Action": "ec2:RunInstances",
			"Resource": "arn:aws:ec2:*:*:instance/*",
			"Condition": {
				"StringLike": {
					"ec2:InstanceType": [
						"p*",
						"g*",
						"inf*",
						"trn*",
						"x*",
						"u-*",
						"z*",
						"mac*"
					]
				}
			}
		},
		{
			"Sid": "ReadOnlyDescribeListEC2RegionRestricted",
			"Effect": "Allow",
			"Action": [
				"ec2:DescribeVpcs",
				"ec2:DescribeSubnets",
				"ec2:DescribeVpcAttribute",
				"ec2:DescribeTags",
				"ec2:DescribeSecurityGroups",
				"ec2:DescribeSecurityGroupRules",
				"ec2:DescribeLaunchTemplates",
				"ec2:DescribeLaunchTemplateVersions",
				"ec2:DescribeNetworkInterfaces",
				"ec2:DescribeAccountAttributes"
			],
			"Resource": "*",
			"Condition": {
				"StringEquals": {
					"aws:RequestedRegion": [
						"<REGION>"
					]
				}
			}
		},
		{
			"Sid": "EC2LifecycleAndSecurity",
			"Effect": "Allow",
			"Action": [
				"ec2:CreateSecurityGroup",
				"ec2:DeleteSecurityGroup",
				"ec2:AuthorizeSecurityGroupIngress",
				"ec2:AuthorizeSecurityGroupEgress",
				"ec2:RevokeSecurityGroupIngress",
				"ec2:RevokeSecurityGroupEgress",
				"ec2:CreateLaunchTemplate",
				"ec2:DeleteLaunchTemplate",
				"ec2:CreateTags",
				"ec2:DeleteTags"
			],
			"Resource": [
				"arn:aws:ec2:*:*:security-group/*",
				"arn:aws:ec2:*:*:launch-template/*",
				"arn:aws:ec2:*:*:instance/*",
				"arn:aws:ec2:*:*:network-interface/*",
				"arn:aws:ec2:*:*:subnet/*",
				"arn:aws:ec2:*:*:vpc/*",
				"arn:aws:ec2:*:*:image/*",
				"arn:aws:ec2:*:*:volume/*",
				"arn:aws:ec2:*:*:snapshot/*"
			]
		}
	]
}
  1. Creating EKS Service Policy.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ReadOnlyDescribeListEKSVersionsRegionRestricted",
            "Effect": "Allow",
            "Action": [
                "eks:DescribeAddonVersions"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestedRegion": [
                        "<REGION>"
                    ]
                }
            }
        },
        {
            "Sid": "ReadOnlyDescribeListEKS",
            "Effect": "Allow",
            "Action": [
                "eks:DescribeCluster",
                "eks:DescribeAddon",
                "eks:DescribePodIdentityAssociation",
                "eks:DescribeNodegroup",
                "eks:ListAddons",
                "eks:ListPodIdentityAssociations"
            ],
            "Resource": [
                "arn:aws:eks:*:<AWS_ACCOUNT_ID>:cluster/*",
                "arn:aws:eks:*:<AWS_ACCOUNT_ID>:nodegroup/*",
                "arn:aws:eks:*:<AWS_ACCOUNT_ID>:addon/*",
                "arn:aws:eks:*:<AWS_ACCOUNT_ID>:podidentityassociation/*"
            ]
        },
        {
            "Sid": "EKSLifecycleAndTag",
            "Effect": "Allow",
            "Action": [
                "eks:CreateCluster",
                "eks:UpdateClusterVersion",
                "eks:UpdateClusterConfig",
                "eks:CreateNodegroup",
                "eks:UpdateNodegroupConfig",
                "eks:UpdateNodegroupVersion",
                "eks:DeleteNodegroup",
                "eks:CreateAddon",
                "eks:UpdateAddon",
                "eks:DeleteAddon",
                "eks:CreatePodIdentityAssociation",
                "eks:DeletePodIdentityAssociation",
                "eks:TagResource",
                "eks:ListClusters"
            ],
            "Resource": [
                "arn:aws:eks:*:<AWS_ACCOUNT_ID>:cluster/*",
                "arn:aws:eks:*:<AWS_ACCOUNT_ID>:nodegroup/*",
                "arn:aws:eks:*:<AWS_ACCOUNT_ID>:addon/*",
                "arn:aws:eks:*:<AWS_ACCOUNT_ID>:podidentityassociation/*"
            ]
        },
        {
            "Sid": "AllowEKSNodegroupSLR",
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:CreateServiceLinkedRole"
            ],
            "Resource": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup"
        },
        {
            "Sid": "EKSDeleteClusterV6",
            "Effect": "Allow",
            "Action": "eks:DeleteCluster",
            "Resource": "arn:aws:eks:*:<AWS_ACCOUNT_ID>:cluster/*"
        }
    ]
}
  1. Creating IAM Service Policy.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyAdminPolicyAttachment",
            "Effect": "Deny",
            "Action": [
                "iam:AttachRolePolicy",
                "iam:PutRolePolicy"
            ],
            "Resource": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/eks-*",
            "Condition": {
                "ArnLike": {
                    "iam:PolicyARN": [
                        "arn:aws:iam::aws:policy/AdministratorAccess",
                        "arn:aws:iam::aws:policy/PowerUserAccess",
                        "arn:aws:iam::aws:policy/*FullAccess"
                    ]
                }
            }
        },
        {
            "Sid": "DenyInlinePolicyEscalation",
            "Effect": "Deny",
            "Action": [
                "iam:PutRolePolicy",
                "iam:PutUserPolicy",
                "iam:PutGroupPolicy"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ReadOnlyDescribeListIAMScoped",
            "Effect": "Allow",
            "Action": [
                "iam:GetRole",
                "iam:ListRolePolicies",
                "iam:ListAttachedRolePolicies",
                "iam:ListInstanceProfilesForRole",
                "iam:GetInstanceProfile",
                "iam:GetPolicy",
                "iam:GetPolicyVersion",
                "iam:ListPolicyVersions",
                "iam:ListAccessKeys"
            ],
            "Resource": [
                "arn:aws:iam::<AWS_ACCOUNT_ID>:role/eks-*",
                "arn:aws:iam::<AWS_ACCOUNT_ID>:instance-profile/eks-*",
                "arn:aws:iam::<AWS_ACCOUNT_ID>:policy/eks-*"
            ]
        },
        {
            "Sid": "ReadOnlyDescribeListUnavoidableStar",
            "Effect": "Allow",
            "Action": "iam:ListRoles",
            "Resource": "*"
        },
        {
            "Sid": "IAMLifecycleRolesPoliciesInstanceProfiles",
            "Effect": "Allow",
            "Action": [
                "iam:CreateRole",
                "iam:TagRole",
                "iam:CreatePolicy",
                "iam:DeletePolicy",
                "iam:DeletePolicyVersion",
                "iam:TagPolicy",
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy",
                "iam:CreateInstanceProfile",
                "iam:TagInstanceProfile",
                "iam:AddRoleToInstanceProfile",
                "iam:RemoveRoleFromInstanceProfile",
                "iam:DeleteInstanceProfile"
            ],
            "Resource": [
                "arn:aws:iam::<AWS_ACCOUNT_ID>:role/eks-*",
                "arn:aws:iam::<AWS_ACCOUNT_ID>:policy/eks-*",
                "arn:aws:iam::<AWS_ACCOUNT_ID>:instance-profile/eks-*"
            ]
        },
        {
            "Sid": "EKSDeleteRoles",
            "Effect": "Allow",
            "Action": "iam:DeleteRole",
            "Resource": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/eks*"
        },
        {
            "Sid": "PassRoleOnlyToEKS",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/eks-*",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": [
                        "eks.amazonaws.com",
                        "ec2.amazonaws.com",
                        "eks-pods.amazonaws.com",
                        "pods.eks.amazonaws.com"
                    ]
                }
            }
        },
        {
            "Sid": "PassRoleForEKSPodIdentityRoles",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": [
                "arn:aws:iam::<AWS_ACCOUNT_ID>:role/eks-*-karpenter-role",
                "arn:aws:iam::<AWS_ACCOUNT_ID>:role/eks-*-backup-recovery-utility-role"
            ]
        }
    ]
}
  1. Creating KMS Service Policy.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "KMSCreateAndList",
            "Effect": "Allow",
            "Action": [
                "kms:CreateKey",
                "kms:ListAliases"
            ],
            "Resource": "*"
        },
        {
            "Sid": "KMSKeyManagementScoped",
            "Effect": "Allow",
            "Action": [
                "kms:PutKeyPolicy",
                "kms:GetKeyPolicy",
                "kms:DescribeKey",
                "kms:GenerateDataKey",
                "kms:Decrypt",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:EnableKeyRotation",
                "kms:GetKeyRotationStatus",
                "kms:ListResourceTags",
                "kms:ScheduleKeyDeletion",
                "kms:CreateAlias",
                "kms:DeleteAlias"
            ],
            "Resource": [
                "arn:aws:kms:*:<AWS_ACCOUNT_ID>:key/*",
                "arn:aws:kms:*:<AWS_ACCOUNT_ID>:alias/*"
            ]
        }
    ]
}
  1. Creating AWS S3 Service Policy.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "S3EncryptionConfigAndStateScoped",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetEncryptionConfiguration",
                "s3:PutEncryptionConfiguration",
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "s3:CreateBucket",
                "s3:GetBucketTagging",
                "s3:GetBucketPolicy",
                "s3:GetBucketAcl",
                "s3:GetBucketCORS",
                "s3:PutBucketTagging",
                "s3:GetBucketWebsite",
                "s3:GetBucketVersioning",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketRequestPayment",
                "s3:GetBucketLogging",
                "s3:GetLifecycleConfiguration",
                "s3:GetReplicationConfiguration",
                "s3:GetBucketObjectLockConfiguration",
                "s3:DeleteBucket",
                "s3:PutBucketVersioning",
                "s3:ListBucketVersions",
                "s3:DeleteObjectVersion",
                "s3:GetObjectTagging"
            ],
            "Resource": "arn:aws:s3:::*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestedRegion": [
                        "<REGION>"
                    ],
                    "aws:PrincipalAccount": "<AWS_ACCOUNT_ID>"
                }
            }
        }
    ]
}
 
 

Description for the JSON components

This section provides information for the permissions mentioned in the JSON file.

IAM Roles

Contact the IT team to create the necessary IAM roles with the following permissions to create and manage AWS EKS resources.

IAM RoleRequired Policies
Amazon EKS cluster IAM Role
Manages the Kubernetes cluster.
- AmazonEKSBlockStoragePolicy
- AmazonEKSClusterPolicy
- AmazonEKSComputePolicy
- AmazonEKSLoadBalancingPolicy
- AmazonEKSNetworkingPolicy
- AmazonEKSVPCResourceController
- AmazonEKSServicePolicy
- AmazonEBSCSIDriverPolicy
Amazon EKS node IAM Role
Communicates with the node.
- AmazonEBSCSIDriverPolicy
- AmazonEC2ContainerRegistryReadOnly
- AmazonEKS_CNI_Policy
- AmazonEKSWorkerNodePolicy
- AmazonSSMManagedInstanceCore

These policies are managed by AWS. For more information about AWS managed policies, refer to AWS managed policies for Amazon Elastic Kubernetes Service in the AWS documentation.

AWS IAM Permissions

The AWS IAM user or role to install PPC must have permissions to create and manage Amazon EKS clusters and the required supporting AWS resources.

EC2 Permissions

CategoryRequired Permissions
Networking & VPCec2:DescribeVpcs
ec2:DescribeSubnets
ec2:DescribeVpcAttribute
ec2:DescribeTags
ec2:DescribeNetworkInterfaces
Security Groupsec2:DescribeSecurityGroups
ec2:DescribeSecurityGroupRules
ec2:CreateSecurityGroup
ec2:DeleteSecurityGroup
ec2:AuthorizeSecurityGroupIngress
ec2:AuthorizeSecurityGroupEgress
ec2:RevokeSecurityGroupIngress
ec2:RevokeSecurityGroupEgress
Launch Templatesec2:DescribeLaunchTemplates
ec2:DescribeLaunchTemplateVersions
ec2:CreateLaunchTemplate
ec2:DeleteLaunchTemplate
Instancesec2:RunInstances
Taggingec2:CreateTags
ec2:DeleteTags

EKS Permissions

CategoryRequired Permissions
Cluster Managementeks:CreateCluster
eks:DescribeCluster
Node Groupseks:CreateNodegroup
eks:DescribeNodegroup
Add-onseks:CreateAddon
eks:DescribeAddon
eks:DescribeAddonVersions
eks:DeleteAddon
eks:ListAddons
Pod Identity Associationseks:CreatePodIdentityAssociation
eks:DescribePodIdentityAssociation
eks:DeletePodIdentityAssociation
eks:ListPodIdentityAssociations
Taggingeks:TagResource

IAM Permissions

CategoryRequired Permissions
Roles & Policiesiam:CreateRole
iam:DeleteRole
iam:TagRole
iam:GetRole
iam:ListRoles
iam:AttachRolePolicy
iam:DetachRolePolicy
iam:ListRolePolicies
iam:ListAttachedRolePolicies
Policiesiam:CreatePolicy
iam:DeletePolicy
iam:TagPolicy
iam:GetPolicy
iam:GetPolicyVersion
iam:ListPolicyVersions
Instance Profilesiam:CreateInstanceProfile
iam:DeleteInstanceProfile
iam:TagInstanceProfile
iam:GetInstanceProfile
iam:AddRoleToInstanceProfile
iam:RemoveRoleFromInstanceProfile
iam:ListInstanceProfilesForRole
Service-linked Roleiam:CreateServiceLinkedRole

AWS S3 Permissions

Required Permissions
s3:ListBucket
s3:PutEncryptionConfiguration
s3:GetEncryptionConfiguration

KMS Permissions

Required Permissions
kms:CreateKey
kms:PutKeyPolicy
kms:GetKeyPolicy

Jump box or local machine

  • A newly provisioned EC2 instance must be used as the jump box for PPC deployment.

  • The jump box must be provisioned in the same AWS region where the PPC cluster will be deployed to ensure proper connectivity and access to regional resources.

  • Supported operating systems: RHEL 10, Debian 13, or Debian 12.

Note: Ensure to retain the original jump box used for installation. The Terraform state files required for cleaning and upgrading the cluster are available on this jump box. A snapshot of the jump box must be maintained to prevent data loss.

AWS Account Details

  • A valid AWS account where Amazon EKS is deployed.

  • The AWS account ID and AWS region must be identified in advance, as all resources are provisioned in the selected region.

Service Quotas

Verify that the AWS account has sufficient service quotas to support the deployment. At a minimum, ensure adequate limits for the following:

  • EC2 instances based on node group size and instance types.
  • VPC and networking limits, including subnets, route tables, and security groups.
  • Elastic IP addresses and Load balancers.

If required, request quota increases through the AWS Service Quotas console before proceeding.

Service Control Policies (SCPs)

The AWS account must not have SCPs that restrict required permissions. In particular, SCPs must not block the following actions:

  • eks:*
  • ec2:*
  • iam:PassRole

Restrictive SCPs may prevent successful cluster creation and resource provisioning.

Virtual Private Cloud (VPC)

  • An existing VPC must be available in the target AWS region.
  • The VPC should be configured to support Amazon EKS workloads.

Subnet Requirements

  • At least two private subnets must be available.
  • Subnets must be distributed across two or more Availability Zones (AZs).

Creating AWS KMS Key and AWS S3 Bucket

Amazon S3 Bucket: An Amazon S3 bucket is required to store critical data such as backups, configuration artifacts, and restore metadata used during installation and recovery workflows. Using a dedicated AWS S3 bucket helps ensure data durability, isolation, and controlled access during cluster operations.

AWS KMS Key: An AWS KMS customer‑managed key is required to encrypt data stored in the AWS S3 bucket. This ensures that sensitive data is protected at rest and allows customers to manage encryption policies, key rotation, and access control in accordance with their security requirements.

Note: The KMS key must allow access to the IAM roles used by the EKS cluster and related services.

The following section explains how to create AWS KMS Key and AWS S3 Bucket. This can be done from the AWS Web UI or using the script.

  1. Create a KMS key for backup bucket.
    The KMS key created is referenced during installation and restore using its KMS ARN, and is validated by the installer.

Before you begin, ensure to have:

  • Access to the AWS account where the KMS key is created.

  • The KMS key can be in the same AWS account as the AWS S3 bucket, or in a different, cross‑account AWS account.

  • The user running the installer must have the permission kms:DescribeKey to describe the KMS key. If this permission is unavailable, then installation and restore fails.

The steps to create a KMS key are available at https://docs.aws.amazon.com/. Follow the KMS key creation steps, but ensure to select the following configurations.

  • On the Key configuration page:
    Select Key type as Symmetric.
    Select Key usage as Encrypt and decrypt.

    These settings are required for encrypting and decrypting AWS S3 objects used by backup and restore operations.

  • On the Key Administrative Permissions page, select the users or roles that can manage the key. The key administrators do not automatically get permission to encrypt or decrypt data, unless these permissions are explicitly granted.

  • On the Define key usage permissions page, grant permissions to the principals that will use the key.

    The user or role running the installation and restore must have the permission kms:DescribeKey to describe the key. This permission is mandatory because the installer validates the KMS key before proceeding. Without this, the installation or restore procedure fails, especially in cross‑account KMS scenarios.

  • On the Edit key policy - optional page, click Edit.

    The KMS key policy controls the access to the encryption key and must be applied before creating the AWS S3 bucket.

    If you are using AWS SSO IAM Identity Center, ensure that the IAM role ARN specified in the KMS key policy includes the full SSO path prefix: aws-reserved/sso.amazonaws.com/.
    For example: arn:aws:iam::<ACCOUNT_ID>:role/aws-reserved/sso.amazonaws.com/<SSO_ROLE_NAME>
    Omitting this path results in KMS key policy creation failures with an InvalidArnException.

The following example shows a key policy that:

  • Allows the PPC bootstrap user to use the KMS key for cluster creation and backup operations.

  • Allows the IAM role to encrypt and decrypt EKS backups.

cat > kms-key-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Id": "key-resource-policy-0",
  "Statement": [
    {
      "Sid": "Allow KMS administrative actions only, no key usage permissions.",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<<ADMIN_AWS_ACCOUNT>>:root"
      },
      "Action": [
        "kms:Create*",
        "kms:Describe*",
        "kms:Enable*",
        "kms:List*",
        "kms:Put*",
        "kms:Update*",
        "kms:Revoke*",
        "kms:Disable*",
        "kms:Get*",
        "kms:Delete*",
        "kms:ScheduleKeyDeletion",
        "kms:CancelKeyDeletion"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Allow user running bootstrap.sh script of the PPC to use the KMS key.",
      "Effect": "Allow",
      "Principal": {
        "AWS": "<<SSO_OR_IAM_USER_ACCOUNT_ARN>>"
      },
      "Action": [
        "kms:DescribeKey",
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncryptFrom",
        "kms:ReEncryptTo",
        "kms:GenerateDataKey",
        "kms:GenerateDataKeyWithoutPlaintext"
      ],
      "Resource": "*"
    },
    {
      "Sid": "Allow backup recovery utility and EKS Node roles KMS key usage permissions, Replace <<<<CLUSTER_NAME>>>> with the name of your EKS cluster.",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<<DEPLOYMENT_AWS_ACCOUNT>>:root"
      },
      "Action": [
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:ReEncryptFrom",
        "kms:ReEncryptTo",
        "kms:GenerateDataKey",
        "kms:GenerateDataKeyWithoutPlaintext",
        "kms:GenerateDataKeyPair",
        "kms:GenerateDataKeyPairWithoutPlaintext",
        "kms:DescribeKey"
      ],
      "Resource": "*",
      "Condition": {
        "ArnLike": {
          "aws:PrincipalArn": [
            "arn:aws:iam::<<DEPLOYMENT_AWS_ACCOUNT>>:role/eks-<<CLUSTER_NAME>>-backup-recovery-utility-role",
            "arn:aws:iam::<<DEPLOYMENT_AWS_ACCOUNT>>:role/eks-<<CLUSTER_NAME>>-node-role"
          ]
        }
      }
    }
  ]
}
EOF

Update the values of the following based on the environment:

  • DEPLOYMENT_AWS_ACCOUNT - AWS account ID.

  • CLUSTER_NAME - EKS cluster name.

  • SSO_OR_IAM_USER_ACCOUNT_ARN - ARN of the IAM role used to run the bootstrap script. The ARN format depends on your authentication method:

    • IAM role – Use the ARN returned by aws sts get-caller-identity.

    • AWS SSO (IAM Identity Center) – Convert the session ARN returned by aws sts get-caller-identity to a full IAM role ARN before using it in the KMS key policy.

      If you are using AWS SSO (IAM Identity Center), the ARN returned by aws sts get-caller-identity is a session ARN and cannot be used directly in an AWS KMS key policy. AWS KMS requires the full IAM role ARN, including the aws-reserved/sso.amazonaws.com/ path. Without this, KMS key policy creation fails with InvalidArnException.

Retrieving the IAM role ARN for KMS key policy

To identify the role used to run the bootstrap script, run the following command:

aws sts get-caller-identity --query Arn --output text
  • IAM role: Use the returned ARN directly.

    arn:aws:iam::<DEPLOYMENT_AWS_ACCOUNT>:role/your-role-name
    
  • AWS SSO (IAM Identity Center): The command returns a session ARN, which must be converted.

    Do not use the session ARN:

    arn:aws:sts::<<DEPLOYMENT_AWS_ACCOUNT>>:assumed-role/AWSReservedSSO_PermissionSetName_abc123/john.doe@company.com
    

    Use this converted IAM role ARN in KMS policy:

    arn:aws:iam::<<DEPLOYMENT_AWS_ACCOUNT>>:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_PermissionSetName_abc123
    

    To convert:

    • Replace arn:aws:sts:: with arn:aws:iam::.
    • Replace assumed-role/ with role/aws-reserved/sso.amazonaws.com/.
    • Remove the session suffix (everything after the last /).

Important: Before initiating restore operation, review and update the KMS key policy to reflect the restore CLUSTER_NAME. Even if the policy was already configured for the source cluster, it must be updated for the new restore cluster. If the policy continues to reference the source cluster name, the IAM role created during restore cannot decrypt the backup data, causing the restore to fail.

After the KMS key is created, note the KMS key ARN. This KMS key ARN is required while creating the AWS S3 backup bucket.

  1. Create an AWS S3 Bucket encrypted with SSE‑KMS
    The AWS S3 bucket encrypted with SSE‑KMS is used as a backup bucket during installation and restore.

Before you begin, ensure to have:

  • Access to the AWS account where the AWS S3 bucket will be created.

  • Permission to create AWS S3 bucket.

  • The user running the installer must have permission to describe the KMS key. Without this permission, installation and restore fails.

The steps to create an AWS S3 bucket are available at https://docs.aws.amazon.com/. Follow the AWS S3 bucket creation steps, but ensure to set the following configurations as mentioned below.

In the Default Encryption section:

  • Select Encryption type as Server-side encryption with AWS Key Management Service keys (SSE-KMS).

  • Select the AWS KMS key ARN. If the KMS key is in a different AWS account than the AWS S3 bucket, then the key will not appear in the AWS console dropdown. In this case, enter the KMS key ARN manually.

  • Enable Bucket Key.

Automatic AWS KMS Key and S3 Bucket Provisioning

When deploying PPC using the bootstrap script, the AWS S3 bucket and KMS key can be provisioned automatically during the installation process, without any separate pre-installation steps.

During the bootstrap script execution, at step 5, you are prompted to choose how to provide the AWS S3 bucket for cluster backups:

Do you want to use an existing AWS S3 bucket, or provision a new one (with KMS key)?
  1) Use existing
  2) Provision new via Tofu (backup-infra)

Select Option 2 - Provision new via Tofu to have the bootstrap script automatically:

  • Create a new AWS KMS key.
  • Create a new AWS S3 bucket encrypted with SSE-KMS.
  • Associate the AWS S3 bucket with the KMS key.

At step 6, when prompted, provide a globally unique bucket name using the following naming rules:

  • Lowercase letters, digits, and hyphens only.
  • Between 3 and 63 characters.
  • Must not already exist.

Note: The AWS S3 bucket and KMS key are created in the same AWS account using this option. For cross-account KMS configurations, follow the steps in the Using AWS Web UI tab.

Use a dedicated AWS S3 bucket per cluster for backup and restore operations to ensure data and encryption isolation. Sharing a bucket across clusters increases the risk of cross-cluster data access or decryption due to IAM misconfiguration.

Blocking Public Access to the AWS S3 Bucket

The PPC bootstrap script does not configure AWS S3 Block Public Access at the per-bucket level. This is by design because many AWS Organizations enforce AWS S3 Block Public Access through Service Control Policies (SCPs) at the account or organization level. This causes per-bucket s3:PutBucketPublicAccessBlock calls to fail with AccessDenied. AWS enabled S3 Block Public Access by default for all new accounts created after April 2023. However, verify the settings manually before proceeding.

Warning: The AWS S3 backup bucket stores highly sensitive data. Ensure that AWS S3 Block Public Access is enforced at the AWS account or organization level to prevent accidental public exposure.

Verify that AWS S3 Block Public Access is enabled at the account level before deploying PPC:

  1. Navigate to the Amazon AWS S3 console.

  2. Click Account and organization settings from the left navigation.

  3. Ensure all four settings are enabled and set to On:

    • Block public access to buckets and objects granted through new access control lists (ACLs)
    • Block public access to buckets and objects granted through any access control lists (ACLs)
    • Block public access to buckets and objects granted through new public bucket or access point policies
    • Block public and cross-account access to buckets and objects through any public bucket or access point policies
  4. If it is set to Off, then click Edit, select the check boxes, and click Save changes.

  5. Verify that the Block Public Access settings for this account are enabled using the following command:

    aws s3control get-public-access-block --account-id $(aws sts get-caller-identity --query Account --output text)
    

    All four fields BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy, RestrictPublicBuckets should be set to true.

Note: To block the permissions at the bucket level, navigate to Buckets > General purpose buckets > select the bucket > Permissions > Block public access (bucket settings).

Zone Requirements

The cluster requires a minimum of two availability zones for high availability. It is required to have two zones available while deploying a PPC.

ZonesSupportedNotes
1NoInstallation fails.
2YesMinimum requirement for High Availability.

Zones are derived from the private subnets which are provided. Each subnet maps to exactly one availability zone. During the installation, the bootstrap script validates that the selected subnets are in different Availability Zones.

Note: Zones cannot be changed after cluster creation.


Last modified : July 29, 2026