Manual component-based installation
This section is intended for enterprise customers who need full control over each stage of the EKS cluster deployment. Use this path when infrastructure stages must be reviewed or approved separately. Use it also when integration with an existing CI/CD pipeline is required. Use it when corporate change-management controls prevent running an all-in-one automated script. All stages must be performed from the same jump box.
Review the Deploying PPC overview and AWS prerequisites before running tofu apply.
Note: If you are performing a standard deployment, complete Configuring for a Standard Deployment before proceeding. Do not add or override
node_group_ami_typein the03_node_groupmodule’sterraform.tfvarsfile, as this will reintroduce secure Bottlerocket AMIs.
Deploying PPC using component-based installation
To deploy PPC using the component-based installation, perform the following steps
| Step | Action | Description |
|---|---|---|
| # | Before you begin | Reviews the jump box requirement and the values to decide before installation. |
| 1 | Preparing a jump box | Prepares a jump box with network access to the EKS cluster and Kubernetes API server. |
| 2 | Exporting AWS credentials | Exports AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN as environment variables to authenticate Terraform and AWS CLI operations. |
| 3 | Downloading and extracting the release PCT | Downloads and extracts the PPC release package on the jump box. |
| 4 | Installing the tools | Installs all required CLI tools (OpenTofu, AWS CLI, kubectl, Helm, and others) on the jump box, either automatically via bootstrap.sh install-tools or manually. |
| 5 | Provisioning the S3 bucket | (Skip if using an existing bucket) Provisions a new S3 bucket and KMS key for storing PPC backup data using the 00_backup_bucket Terraform module. |
| 6 | Modifying and applying terraform.tfvars files | Configures and applies five Terraform modules in sequence to provision all PPC infrastructure components. |
| 6a | 01_iam_roles module | Creates the EKS cluster IAM role, node group IAM role, and service account IAM roles required for the deployment. |
| 6b | 02_eks_cluster module | Provisions the EKS cluster, VPC security group, and networking add-ons (VPC CNI, kube-proxy). |
| 6c | 03_node_group module | Creates the EKS worker node group with the specified instance size, architecture, and subnet configuration. |
| 6d | 04_eks_addons module | Installs EKS add-ons including CoreDNS, Metrics Server, EBS CSI driver, and snapshot controller. |
| 6e | 05_helm_releases module | Deploys all PPC platform Helm charts including Karpenter, Velero, Envoy Gateway, and Insight. This step may take 15–20 minutes. |
| 7 | Verifying the installation | Confirms all cluster nodes are in Ready state, and all pods are in Running state. |
Before you begin
Ensure to have the following prerequisites before proceeding with the installation.
Values decided by user
| Value | Example |
|---|---|
| AWS credentials | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN |
| Cluster name | my-cluster |
| VPC ID | vpc-0abc123 |
| Two private subnet IDs | subnet-aaa, subnet-bbb |
| Ingress FQDN | myapp.example.com |
| S3 backup bucket name | my-backup-bucket (existing) or provision one in Step 5 |
| Image registry endpoint | <Container_Registry_Path>Note: If deploying from the Protegrity Container Registry, use registry.protegrity.com:9443. Specify the local registry endpoint if a local registry is used. |
| Registry username and password | Provided by organization |
Using Standard Bottlerocket AMI Deployment
By default, PPC deploys using the secure (FIPS) Bottlerocket AMI. Before choosing the standard Bottlerocket AMI, verify whether the secure AMI is available in your target region.
Run the following AWS CLI command, replacing <region>, <eks-version>, and <arch> with your values:
Architecture value: Use x86_64 for amd64 nodes, or arm64 for arm64 (Graviton) nodes. Do not use amd64, amd, or arm. The SSM parameter path must match exactly, or the lookup will fail.
EKS version value: Use the Kubernetes version with which the cluster will be created. This is the eks_cluster_version value in the 02_eks_cluster module in variables.tf file, and the default value is 1.35.
aws ssm get-parameter \
--region <region> \
--name "/aws/service/bottlerocket/aws-k8s-<eks-version>-fips/<arch>/latest/image_id"
For example, amd64 nodes, EKS 1.35, and us-east-1:
aws ssm get-parameter \
--region us-east-1 \
--name "/aws/service/bottlerocket/aws-k8s-1.35-fips/x86_64/latest/image_id"
Interpret the result as follows:
Returns an image ID: The secure Bottlerocket AMI is published in that region. Proceed with the default (secure) deployment. No additional steps are required.
Returns
ParameterNotFound: Before concluding the AMI is unavailable, verify the following:<arch>is exactlyx86_64orarm64.<eks-version>matches theeks_cluster_versionvalue in the02_eks_clustermodule (default1.35). For example,aws-k8s-1.35-fips.
Optionally, confirm which EKS versions AWS currently offers in the region. This works before any cluster exists.
aws eks describe-cluster-versions --region <region> --query "clusterVersions[].clusterVersion" --output table
If the command returns ParameterNotFound, then the secure Bottlerocket AMI is not published in that region, and you must complete the additional requirements. For the additional requirements, refer to Configuring for a Standard Deployment.
Deploying PPC
To deploy PPC using component-based installation, perform the following steps:
1. Preparing a jump box
Create a jump box or use an existing one that has network access to the EKS cluster. The jump box must be able to access the Kubernetes API server endpoint.
2. Exporting AWS credentials
The installation process uses Terraform to provision and manage AWS resources. These resources include VPCs, EKS clusters, IAM roles, and S3 buckets. The AWS credentials must be exported as environment variables to authenticate these operations.
Note: While using temporary credentials, such as AWS STS credentials, ensure the session token is included. Also confirm that the credentials have not expired before proceeding.
CLI login using AWS SSO (IAM Identity Center) is not supported. Export IAM user credentials or temporary STS credentials as environment variables.
If the components are installed by different users, ensure that each user must export their AWS credentials. This ensures that all the required access and permissions are available.
To export the AWS credentials, run the following commands:
export AWS_ACCESS_KEY_ID=<your-access-key-id>
export AWS_SECRET_ACCESS_KEY=<your-secret-access-key>
export AWS_SESSION_TOKEN=<your-session-token>
3. Downloading and extracting the release PCT
To download and extract the PCT, refer to Preparing for PPC deployment.
4. Installing the tools
The following tools and minimum versions are required for the component-based installation. Ensure they are installed on your jump box before proceeding, or use the bootstrap.sh install-tools command to install them automatically.
After downloading and extracting the PPC-K8S-ALL_1.2.0.x.tar as described in Preparing for PPC deployment, run the following command to install the required tools:
Note: For more information about the PCT, refer to My.Protegrity or the release notes.
./bootstrap.sh install-tools --cloud aws
Alternatively, the following tools must be installed and available on the jump box before starting.
| Tools Name | Description | Minimum Required Version |
|---|---|---|
| OpenTofu | Required to manage infrastructure as code (IaC) and provision cloud resources. | 1.11.5 |
| AWS CLI | Required to communicate with AWS and manage AWS resources. | 2.36.7 |
| kubectl | Required to communicate with and manage Kubernetes clusters. | 1.36.1 |
| Helm | Required to deploy and manage Kubernetes packages and applications. | 3.21.0 |
| skopeo | Required to inspect, copy, and transfer container images between registries. | 1.18.0 |
| jq | Required to parse, filter, and process JSON data. | 1.7 |
| bc | Required for version comparisons and resource calculations. | 1.07.1 |
| ssh-keygen | Required to generate and manage SSH keys for secure access to deployment environments. | OpenSSH_10.0p2 Debian-7+deb13u4 |
| oras | Required to pull OCI artifacts, including non-container deployment packages, from registries. | 1.3.3 |
| cmctl | Required to validate, manage, and troubleshoot cert-manager TLS certificates. | 2.5.0 |
5. Provisioning the S3 bucket
This step is required if a new S3 bucket is to be provisioned for storing the backup data. If an existing S3 bucket is to be used, note the bucket name and KMS key ARN. These values are required for the installation process. Then skip to the next step.
a. To navigate to 00_backup_bucket directory, run the following command:
export PPC_DEPLOY_DIR=<path to PPC deployment directory>
cd "$PPC_DEPLOY_DIR/iac/aws/cluster/modules/00_backup_bucket"
b. Edit the terraform.tfvars file to provide the following information:
cluster_name = "<cluster-name>"
s3_bucket_name = "<globally-unique-bucket-name>"
kms_key_alias_name = "alias/pty-backup-<cluster-name>-key"
aws_region = "<region>"
c. To apply the terraform configuration, run the following command:
tofu init
tofu plan # review the proposed changes before applying
tofu apply # when prompted with "Enter a value:", type "yes"
After the S3 bucket is provisioned successfully, note the bucket name and KMS key ARN. These values are required during the installation process.
d. To sync the Terraform state file to the S3 bucket, run the following command:
# Navigate to the bootstrap-scripts directory
cd <package-root>/bootstrap-scripts
# Run the script to sync the backup data to the S3 bucket
./sync-backup-bucket-state-to-s3.sh
e. Verify the S3 bucket configuration and confirm the Terraform configuration and state files were uploaded. These checks confirm that the bucket is ready for backups. They also confirm that the KMS key is enabled with rotation. They further confirm that the artifacts needed to manage the bucket are stored in S3. Run the checks from the package root.
# --- Stage 00 parameters ---
export CLUSTER_NAME="<cluster-name>" # e.g. prod-eks-cluster
export REGION="<region>" # e.g. us-east-1
export BUCKET_NAME="<s3-bucket-name>" # e.g. modular-bucket
export KMS_ALIAS="<kms-key-alias>" # e.g. alias/pty-backup-<cluster-name>-key
# a. Bucket exists
aws s3api head-bucket --bucket "$BUCKET_NAME" --region "$REGION" && echo "Bucket exists"
# b. Versioning enabled
aws s3api get-bucket-versioning --bucket "$BUCKET_NAME" --region "$REGION" --output table
# c. Default encryption is KMS
aws s3api get-bucket-encryption --bucket "$BUCKET_NAME" --region "$REGION" \
--query "ServerSideEncryptionConfiguration.Rules[].ApplyServerSideEncryptionByDefault" --output table
# d. KMS key enabled + rotation
aws kms describe-key --key-id "$KMS_ALIAS" --region "$REGION" \
--query "KeyMetadata.{KeyId:KeyId, Enabled:Enabled, State:KeyState}" --output table
KMS_KEY_ID=$(aws kms describe-key --key-id "$KMS_ALIAS" --region "$REGION" --query "KeyMetadata.KeyId" --output text)
aws kms get-key-rotation-status --key-id "$KMS_KEY_ID" --region "$REGION" --output table
# e. tfvars + state uploaded
aws s3 ls "s3://$BUCKET_NAME/infrastructure-manifest/$CLUSTER_NAME/tfvars/00_backup_bucket/" --region "$REGION"
aws s3 ls "s3://$BUCKET_NAME/infrastructure-manifest/$CLUSTER_NAME/states/" --region "$REGION"
# f. Record outputs
tofu output
The verification is complete when the bucket exists, versioning is Enabled, and encryption is aws:kms. The KMS key must be enabled with rotation. The tfvars and state files must be present in S3. Record s3_bucket_name and kms_key_arn.
6. Modifying and applying terraform.tfvars files
The iac/aws/cluster/modules/ directory contains the Terraform modules for the PPC installation. To enter details in the terraform.tfvars file, navigate to the appropriate module directory and edit the file accordingly.
After modifying the terraform.tfvars file, apply the changes.
01_iam_roles module
a. To navigate to 01_iam_roles directory, run the following command:
export PPC_DEPLOY_DIR=<path to PPC deployment directory>
cd "$PPC_DEPLOY_DIR/iac/aws/cluster/modules/01_iam_roles"
b. Edit the terraform.tfvars file to provide the following information:
aws_region = "<region>"
eks_cluster_name = "<cluster-name>"
backup_bucket = "<s3-bucket-name>"
backup_bucket_kms_arn = "<kms-key-arn>"
c. To apply the terraform configuration, run the following command:
tofu init
tofu plan # review the proposed changes before applying
tofu apply # when prompted with "Enter a value:", type "yes"
d. Verify the IAM roles, customer-managed policies, role policy attachments, and node instance profile created by this module. The commands also confirm the module’s terraform.tfvars backup is in S3. They also display the role ARNs needed by later modules. Run them from the 01_iam_roles module directory:
# --- Stage 01 parameters ---
export CLUSTER_NAME="<cluster-name>"
export REGION="<region>"
export BUCKET_NAME="<s3-bucket-name>"
# a. Four IAM roles
aws iam list-roles --query "Roles[?contains(RoleName, '${CLUSTER_NAME}')].[RoleName, Arn]" --output table
# b. Customer-managed policies
aws iam list-policies --scope Local \
--query "Policies[?contains(PolicyName, '${CLUSTER_NAME}')].[PolicyName, Arn]" --output table
# c. Node role managed policies
aws iam list-attached-role-policies --role-name "eks-${CLUSTER_NAME}-node-role" \
--query "AttachedPolicies[].PolicyName" --output table
# d. Cluster role managed policies
aws iam list-attached-role-policies --role-name "eks-${CLUSTER_NAME}-cluster-role" \
--query "AttachedPolicies[].PolicyName" --output table
# e. Node instance profile
aws iam get-instance-profile --instance-profile-name "eks-${CLUSTER_NAME}-node-profile" \
--query "InstanceProfile.{Name:InstanceProfileName, Role:Roles[0].RoleName}" --output table
# f. tfvars backed up
aws s3 ls "s3://${BUCKET_NAME}/infrastructure-manifest/${CLUSTER_NAME}/tfvars/01_iam_roles/" --region "$REGION"
# g. Record role ARNs
tofu output
The verification is complete when all four roles (cluster-role, node-role, karpenter-role, and backup-recovery-utility-role) and four local policies exist. The node and cluster managed policies must be attached. The node instance profile must be linked. The terraform.tfvars file must be present in S3.
02_eks_cluster module
a. To navigate to 02_eks_cluster directory, run the following command:
export PPC_DEPLOY_DIR=<path to PPC deployment directory>
cd "$PPC_DEPLOY_DIR/iac/aws/cluster/modules/02_eks_cluster"
b. Edit the terraform.tfvars file to provide the following information.
Note: The security group is created in AWS using the name specified by the
security_group_namevalue in this file.
Important: The security group name must follow the exact format
<cluster-name>_SG. TheSGmust be in uppercase. This value is used as the AWS Name tag on the worker security group. Protegrity components discover the security group by matching this tag value exactly. Tag values are case-sensitive. Any other format, for example, lowercase _sg or a custom name, will cause those components to fail. The security group name must also not start withSG.
aws_region = "<region>"
eks_cluster_name = "<cluster-name>"
backup_bucket = "<s3-bucket-name>"
# Important: The security group name must follow the exact format <cluster-name>_SG.
# The SG must be in uppercase. This value is used as the AWS Name tag on the worker security group.
# Protegrity components discover the security group by matching this tag value exactly.
# Tag values are case-sensitive. Any other format, for example, lowercase _sg or a custom name, will cause those components to fail.
# The security group name must also not start with SG.
# --- Networking ---
vpc_id = "<vpc-id>"
security_group_name = "<cluster-name>_SG" # Must match this format exactly
private_subnet_ids = [
"<subnet-a>",
"<subnet-b>"
]
# --- Tagging ---
owner_email = "<owner_email>"
# --- Access Entries (optional) ---
# Add IAM users/roles that need kubectl / tofu access beyond the original installer.
additional_access_entries = [
# {
# principal_arn = "<principal-arn>"
# },
]
c. To apply the terraform configuration, run the following command:
tofu init
tofu plan # review the proposed changes before applying
tofu apply # when prompted with "Enter a value:", type "yes"
d. After applying the configuration, verify the setup. Check the EKS cluster, security group, add-ons, subnet tags, and kubeconfig context by running the following commands:
# --- Stage 02 parameters ---
export CLUSTER_NAME="<cluster-name>"
export REGION="<region>"
export BUCKET_NAME="<s3-bucket-name>"
export SG_NAME="${CLUSTER_NAME}_SG" # worker SG name (uppercase SG)
# a. Cluster ACTIVE
aws eks describe-cluster --name "$CLUSTER_NAME" --region "$REGION" \
--query "cluster.{Name:name, Status:status, Version:version, Endpoint:endpoint}" --output table
# b. No nodes yet (expected)
kubectl get nodes # expected: No resources found (node group is Stage 03)
# c. Worker security group exists (exact name)
aws ec2 describe-security-groups --filters "Name=tag:Name,Values=${SG_NAME}" --region "$REGION" \
--query "SecurityGroups[].{Name:Tags[?Key=='Name']|[0].Value, ID:GroupId, VPC:VpcId}" --output table
# d. VPC CNI + kube-proxy ACTIVE
aws eks list-addons --cluster-name "$CLUSTER_NAME" --region "$REGION" --output table
for addon in vpc-cni kube-proxy; do
aws eks describe-addon --cluster-name "$CLUSTER_NAME" --addon-name "$addon" --region "$REGION" \
--query "addon.{Name:addonName, Status:status, Version:addonVersion}" --output table
done
# e. Subnet tags (cluster + Karpenter discovery)
aws ec2 describe-subnets --region "$REGION" \
--filters "Name=tag:kubernetes.io/cluster/${CLUSTER_NAME},Values=shared" \
--query "Subnets[].{Subnet:SubnetId, AZ:AvailabilityZone}" --output table
aws ec2 describe-subnets --region "$REGION" \
--filters "Name=tag:karpenter.sh/discovery/${CLUSTER_NAME},Values=true" \
--query "Subnets[].SubnetId" --output table
# f. kubeconfig context added
kubectl config get-contexts | grep "$CLUSTER_NAME"
# g. tfvars backed up
aws s3 ls "s3://${BUCKET_NAME}/infrastructure-manifest/${CLUSTER_NAME}/tfvars/02_eks_cluster/" --region "$REGION"
# h. Record outputs
tofu output
The verification is complete when the cluster is ACTIVE and kubectl get nodes returns No resources found. The <cluster>_SG security group must exist, and both add-ons must be ACTIVE. The required subnet tags must be present. The kubeconfig context must be added, and the terraform.tfvars file must be present in S3. Record private_subnet_ids, vpc_id, vpc_cidr_block, and worker_security_group_id.
03_node_group module
a. To navigate to 03_node_group directory, run the following command:
export PPC_DEPLOY_DIR=<path to PPC deployment directory>
cd "$PPC_DEPLOY_DIR/iac/aws/cluster/modules/03_node_group"
b. Edit the terraform.tfvars file to provide the following information.
Note: Use the private subnet IDs from the VPC where the EKS cluster is provisioned while installing the
02_eks_clustermodule.
aws_region = "<region>"
eks_cluster_name = "<cluster-name>"
backup_bucket = "<s3-bucket-name>"
# --- System Node Group ---
node_group_name = "<node-group-name>"
private_subnet_ids = [
"<subnet-a>",
"<subnet-b>"
]
architecture = "<amd64/arm64>"
node_group_desired_size = 2
node_group_max_size = 2
node_group_min_size = 1
Note for standard deployments: If you completed the steps in Configuring for a Standard Deployment, the
node_group_ami_type_mapdefault values in variables.tf file have already been changed. The defaults are nowBOTTLEROCKET_x86_64(amd64) orBOTTLEROCKET_ARM_64(arm64). Do not add or overridenode_group_ami_typein the terraform.tfvars file. Doing so reintroduces secure Bottlerocket AMIs.
c. To apply the terraform configuration, run the following command:
tofu init
tofu plan # review the proposed changes before applying
tofu apply # when prompted with "Enter a value:", type "yes"
d. After applying the configuration, verify that the node group and worker nodes are healthy, the expected labels and taint are present, the launch template and EC2 instances exist, and the terraform.tfvars backup is in S3. Run these commands from the 03_node_group module directory:
# --- Stage 03 parameters ---
export CLUSTER_NAME="<cluster-name>"
export REGION="<region>"
export BUCKET_NAME="<s3-bucket-name>"
export NODE_GROUP_NAME="<node-group-name>" # e.g. modular-nodegroup_NG
# a. Node group ACTIVE
aws eks describe-nodegroup --cluster-name "$CLUSTER_NAME" --nodegroup-name "$NODE_GROUP_NAME" --region "$REGION" \
--query "nodegroup.{Name:nodegroupName, Status:status, AMIType:amiType, Instances:instanceTypes, Scaling:scalingConfig}" --output table
# b. Nodes Ready
kubectl get nodes -o wide
# c. Labels + taint
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.role}{"\t"}{.metadata.labels.nodepool-owner}{"\n"}{end}'
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.taints}{"\n"}{end}'
# d. Launch template exists (note: --launch-template-ids, NOT a filter)
aws ec2 describe-launch-templates --region "$REGION" \
--launch-template-ids "$(tofu output -raw launch_template_id)" \
--query "LaunchTemplates[].{Name:LaunchTemplateName, ID:LaunchTemplateId, Default:DefaultVersionNumber}" --output table
# Alternative by name:
# aws ec2 describe-launch-templates --region "$REGION" \
# --filters "Name=launch-template-name,Values=${NODE_GROUP_NAME}-*" \
# --query "LaunchTemplates[].{Name:LaunchTemplateName, ID:LaunchTemplateId, Default:DefaultVersionNumber}" --output table
# e. Worker EC2 instances running
aws ec2 describe-instances --region "$REGION" \
--filters "Name=tag:eks:nodegroup-name,Values=${NODE_GROUP_NAME}" "Name=instance-state-name,Values=running" \
--query "Reservations[].Instances[].{ID:InstanceId, Type:InstanceType, AZ:Placement.AvailabilityZone, State:State.Name}" --output table
# f. tfvars backed up
aws s3 ls "s3://${BUCKET_NAME}/infrastructure-manifest/${CLUSTER_NAME}/tfvars/03_node_group/" --region "$REGION"
# g. Record outputs + node OS details for Stage 05
tofu output
kubectl get nodes -o jsonpath='{.items[0].status.nodeInfo.osImage}'; echo
The verification is complete when the node group is ACTIVE and the desired number of nodes are Ready. Each node must have the role=system and nodepool-owner=ppc labels and the CriticalAddonsOnly taint. The launch template and running instances must exist. The terraform.tfvars file must be present in S3. Record node_group_name, the node architecture, and the node OS enum for Stage 05. The osImage output is informational. Do not copy it directly into node_os. For example, Bottlerocket OS 1.66.0 (aws-k8s-1.35-fips) on amd64 maps to architecture = "amd64". The same node maps to node_os = "BOTTLEROCKET_x86_64_FIPS".
04_eks_addons module
a. To navigate to 04_eks_addons directory, run the following command:
export PPC_DEPLOY_DIR=<path to PPC deployment directory>
cd "$PPC_DEPLOY_DIR/iac/aws/cluster/modules/04_eks_addons"
b. Edit the terraform.tfvars file to provide the following information:
aws_region = "<region>"
eks_cluster_name = "<cluster-name>"
backup_bucket = "<s3-bucket-name>" #
# --- Storage classes ---
storage_class_name = "pty-sc" # default (general-purpose) StorageClass; must match Stage 05
# --- Upgrade mode only ---
# Set to "~/.kube/config" when upgrading an existing cluster;
# leave empty ("") for a fresh install.
kubeconfig_path = ""
c. To apply the terraform configuration, run the following command:
tofu init
tofu plan # review the proposed changes before applying
tofu apply # when prompted with "Enter a value:", type "yes"
Note: This stage waits for all nodes from Stage 03 to reach
Readystatus before installing add-ons.
d. After applying the configuration, verify the add-ons and related resources. Confirm that all EKS add-ons are active and that the default StorageClass settings are correct. Confirm that CoreDNS, Metrics Server, and the EBS CSI controller are running. Confirm that the Pod Identity associations exist and that the terraform.tfvars backup is in S3. Run these commands from the 04_eks_addons module directory:
# --- Stage 04 parameters ---
export CLUSTER_NAME="<cluster-name>"
export REGION="<region>"
export BUCKET_NAME="<s3-bucket-name>"
export STORAGE_CLASS="<storage-class-name>" # default pty-sc
# a. All add-ons ACTIVE
aws eks list-addons --cluster-name "$CLUSTER_NAME" --region "$REGION" --output table
for addon in coredns metrics-server aws-ebs-csi-driver snapshot-controller eks-pod-identity-agent; do
aws eks describe-addon --cluster-name "$CLUSTER_NAME" --addon-name "$addon" --region "$REGION" \
--query "addon.{Name:addonName, Status:status, Version:addonVersion}" --output table
done
# b. Default StorageClass exists
kubectl get storageclass
# c. StorageClass details
kubectl get storageclass "$STORAGE_CLASS" \
-o jsonpath='{.provisioner}{"\t"}{.reclaimPolicy}{"\t"}{.volumeBindingMode}{"\n"}'
# d. CoreDNS + Metrics Server running
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl get pods -n kube-system -l app.kubernetes.io/name=metrics-server
# e. EBS CSI controller running
kubectl get deployment ebs-csi-controller -n kube-system \
-o jsonpath='{.status.readyReplicas}/{.status.replicas} ready{"\n"}'
kubectl get pods -n kube-system -l app=ebs-csi-controller
# f. Pod Identity associations
aws eks list-pod-identity-associations --cluster-name "$CLUSTER_NAME" --region "$REGION" \
--query "associations[].{Namespace:namespace, ServiceAccount:serviceAccount}" --output table
# g. tfvars backed up
aws s3 ls "s3://${BUCKET_NAME}/infrastructure-manifest/${CLUSTER_NAME}/tfvars/04_eks_addons/" --region "$REGION"
# h. Record outputs
tofu output
The verification is complete when all five add-ons are ACTIVE. ${STORAGE_CLASS} must be the default StorageClass with the ebs.csi.aws.com provisioner, a Retain reclaim policy, and WaitForFirstConsumer volume binding mode. CoreDNS, Metrics Server, and the EBS CSI controller must be running. Both Pod Identity associations (karpenter and backup-recovery-utility) must exist. The terraform.tfvars file must be present in S3.
05_helm_releases module
a. To navigate to 05_helm_releases directory, run the following command:
export PPC_DEPLOY_DIR=<path to PPC deployment directory>
cd "$PPC_DEPLOY_DIR/iac/aws/cluster/modules/05_helm_releases"
b. Edit the terraform.tfvars file to provide the following information.
The default node OS is BOTTLEROCKET_x86_64_FIPS. Set node_os to the platform enum, not the raw osImage string returned by kubectl. For FIPS Bottlerocket nodes, use BOTTLEROCKET_x86_64_FIPS for amd64 or BOTTLEROCKET_ARM_64_FIPS for arm64.
The following fields must be updated with environment-specific values:
| Field | Description |
|---|---|
aws_region | AWS region where the cluster is deployed. |
eks_cluster_name | Name of the EKS cluster. |
backup_bucket | Name of the S3 bucket for backups. |
backup_bucket_kms_arn | ARN of the KMS key used to encrypt the backup bucket. |
architecture | Node architecture: amd64 or arm64. |
node_os | Node OS enum matching the node architecture and FIPS status, such as BOTTLEROCKET_x86_64_FIPS. Do not use the raw kubectl osImage output. |
global_image_reg | Container image registry endpoint: <Container_Registry_Path>.Note: If deploying from the Protegrity Container Registry, use registry.protegrity.com:9443. Specify the local registry endpoint if a local registry is used. |
ingress_fqdn | Fully qualified domain name for the ingress. |
owner_email | Email address of the cluster owner. |
vpc_cidr_block | CIDR block of the VPC, used to derive internal proxy CIDRs. |
The following fields have default values and must be left unchanged for a fresh installation:
| Field | Default value | Notes |
|---|---|---|
harbor_secret | "harbor-secret" | Fixed secret name; do not change. |
private_subnet_ids | [] | Populated automatically by bootstrap.sh from stage 02 state. |
restore | false | Set to true only when restoring from a backup. |
backup_name | "authnz-postgresql-schedule-backup" | Default backup schedule name; change only if restoring a custom backup. |
insight_backup_name | "" | Leave empty unless restoring an Insight backup. |
kubeconfig_path | "" | Leave empty for a fresh install; set to ~/.kube/config only for upgrades. |
is_upgrade | false | Set to true only when upgrading an existing cluster. |
skip_validations | false | Leave as false unless instructed otherwise. |
aws_region = "<region>"
eks_cluster_name = "<cluster-name>"
backup_bucket = "<s3-bucket-name>"
backup_bucket_kms_arn = "<kms-key-arn>"
storage_class_name = "<storage-class-name>"
backup_storage_class_name = "<backup-storage-class-name>"
# --- Readiness ---
architecture = "amd64"
node_os = "BOTTLEROCKET_x86_64_FIPS"
# --- Karpenter instance families (must be org SCP-approved, p-6aysnndi) ---
karpenter_instance_families = ["t3", "t4g"] # amd64: m5, m6i, c5, r5, t3, t3a; arm64: see arm64_instance_families below
arm64_instance_families = ["t4g"] # subset of karpenter_instance_families classified as arm64 (Graviton)
# --- Registry ---
global_image_reg = "<Container_Registry_Path>"
harbor_secret = "harbor-secret"
# --- Ingress ---
ingress_fqdn = "<fqdn>"
# --- Owner ---
owner_email = "<owner-email>"
# --- CLI users (enrolled via bootstrap.sh access add-cli-user) ---
cli_user_public_keys = {} # e.g. { "jane.doe" = "ssh-rsa AAAA... jane.doe@host" } - on FIPS clusters only RSA (>=2048 bits) and ECDSA keys are accepted, not Ed25519/DSA
# cli_user_public_keys is an optional map of additional CLI users
# who should be granted SSH access to the cluster. Add entries
# as username-to-public-key pairs, for example: {"jane.doe" = "ssh-rsa AAAA... jane.doe@host"}
# This is used to enroll additional users through bootstrap.sh access add-cli-user.
# On FIPS-enabled clusters, only RSA keys with a minimum length of 2048 bits
# and ECDSA keys are accepted. Ed25519 and DSA keys are not supported.
# --- Networking (used to derive internal proxy CIDRs) ---
vpc_cidr_block = "<cidr>"
# --- Envoy Gateway (LoadBalancer subnet discovery) ---
private_subnet_ids = []
# --- Restore ---
restore = false
backup_name = "authnz-postgresql-schedule-backup"
insight_backup_name = ""
# --- Upgrade mode only ---
# Set to "~/.kube/config" when upgrading an existing cluster;
# leave empty ("") for a fresh install.
kubeconfig_path = ""
is_upgrade = false
skip_validations = false
c. Save the file and exit the editor.
d. This step must be performed only if registry needs an authentication. Do not put them in the tfvars file.
To enter registry credentials using the environment variables, run the following commands:
export TF_VAR_username="<registry-username>"
export TF_VAR_password="<registry-password>"
e. To apply the terraform configuration, run the following command:
tofu init
tofu plan # review the proposed changes before applying
tofu apply # when prompted with "Enter a value:", type "yes"
Note: This process may take 15–20 minutes to get completed. Karpenter nodes are provisioned on demand after the NodePool is created.
f. After applying the configuration, verify that all Helm releases are deployed. Confirm that the backup StorageClass exists and that Karpenter and Velero are running. Confirm that Envoy Gateway has provisioned a LoadBalancer and that Insight is healthy. Confirm that its bootstrap job has succeeded and that the terraform.tfvars backup is in S3. Run these commands from the 05_helm_releases module directory:
# --- Stage 05 parameters ---
export CLUSTER_NAME="<cluster-name>"
export REGION="<region>"
export BUCKET_NAME="<s3-bucket-name>"
export INSIGHT_NS=pty-insight
# a. All Helm releases deployed
helm list -A
# b. Backup StorageClass auto-created by this stage
kubectl get storageclass # expect pty-bkp in addition to pty-sc
# c. Karpenter running + NodePool/EC2NodeClass present
kubectl get pods -n karpenter
kubectl get nodepools
kubectl get ec2nodeclasses
# d. Velero running
kubectl get pods -n pty-backup-recovery
# e. Envoy Gateway running + LoadBalancer provisioned
kubectl get pods -n api-gateway
kubectl get svc -n api-gateway \
-o jsonpath='{range .items[?(@.spec.type=="LoadBalancer")]}{.metadata.name}{"\t"}{.status.loadBalancer.ingress[0].hostname}{"\n"}{end}'
# f. Insight pods healthy (incl. OpenSearch + Dashboards)
kubectl get pods -n "$INSIGHT_NS"
kubectl get pods -n "$INSIGHT_NS" -l app=opensearch-dashboards
# g. Insight bootstrap job succeeded (post-install hook)
kubectl get job -n "$INSIGHT_NS" initialize-opensearch-repository \
-o jsonpath='{.status.succeeded} succeeded / {.status.failed} failed{"\n"}'
# h. Cluster-wide: no unhealthy pods
kubectl get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded
# i. tfvars backed up
aws s3 ls "s3://${BUCKET_NAME}/infrastructure-manifest/${CLUSTER_NAME}/tfvars/05_helm_releases/" --region "$REGION"
If the bootstrap job fails with a 403 anonymous/proxy-auth error (opendistro_security_anonymous), it indicates an OpenSearch Dashboards readiness or identity issue. It is not a node_os issue. Confirm the Dashboards pod is fully Ready, then rerun tofu apply from the 05_helm_releases module. This applies the corrected node_os and triggers a fresh post-install bootstrap attempt.
The verification is complete when all Helm releases are deployed and the pty-bkp backup StorageClass is present. Karpenter is running, and its NodePool and EC2NodeClass exist. Velero is running. Envoy Gateway is running with an external LoadBalancer address. The Insight pods, including OpenSearch Dashboards, are healthy. The initialize-opensearch-repository job has succeeded. The terraform.tfvars file is present in S3. No pods remain in a phase other than Running or Succeeded.
7. Verifying the installation
To verify the installation, run the following command:
# --- parameters ---
export CLUSTER_NAME="<cluster-name>"
export REGION="<region>"
kubectl get nodes # all Ready
kubectl get pods -A # all Running / Completed
All the nodes should be in the Ready state, and all the pods should be in the Running state.
Configuring for a Standard Deployment
Note: The following instructions are optional and only required for configuring a standard PPC deployment on AWS. Skip these steps if you have already installed the secure Bottlerocket AMIs.
By default, the PCT is configured to deploy a cluster using secure Bottlerocket AMIs. To deploy a standard cluster, the Terraform configuration files must be modified to use the standard Bottlerocket AMI types and SSM parameter paths before running the bootstrap script or the component-based installation.
For a standard PPC deployment on AWS EKS, perform the following steps:
Ensure that you have downloaded and extracted the PCT. For more information, refer to Preparing for PPC deployment.
Update the node group AMI type map in the
/03_node_group/variables.tffile.
The node_group_ami_type_map variable defines the fallback EKS AMI type used per node architecture when node_group_ami_type is not explicitly set. The secure Bottlerocket AMI defaults must be replaced with the corresponding standard Bottlerocket AMI types.
a. Navigate to /03_node_group directory.
cd iac/aws/cluster/modules/03_node_group/
b. Edit the variables.tf file to make the following changes.
Change from (secure defaults):
variable "node_group_ami_type_map" {
description = "Fallback EKS AMI type per architecture, used when node_group_ami_type is empty."
type = map(string)
default = {
amd64 = "BOTTLEROCKET_x86_64_FIPS"
arm64 = "BOTTLEROCKET_ARM_64_FIPS"
}
}
Change to (standard values):
variable "node_group_ami_type_map" {
description = "Fallback EKS AMI type per architecture, used when node_group_ami_type is empty."
type = map(string)
default = {
amd64 = "BOTTLEROCKET_x86_64"
arm64 = "BOTTLEROCKET_ARM_64"
}
}
- Update the Karpenter AMI SSM parameter path in the
/05_helm_releases/main.tffile.
The karpenter_fips_ami_ssm_parameter value specifies the AWS Systems Manager (SSM) parameter path that Karpenter uses to resolve the correct Bottlerocket AMI for worker nodes. The default path targets the secure Bottlerocket AMI. For a standard cluster, remove the -fips segment from the EKS version portion of the path.
a. Navigate to /05_helm_releases directory.
cd iac/aws/cluster/modules/05_helm_releases/
b. Edit the main.tf file to make the following changes.
Change from (secure SSM path):
karpenter_fips_ami_ssm_parameter = "/aws/service/bottlerocket/aws-k8s-${data.aws_eks_cluster.this.version}-fips/${local.karpenter_ami_arch}/latest/image_id"
Change to (standard SSM path):
karpenter_fips_ami_ssm_parameter = "/aws/service/bottlerocket/aws-k8s-${data.aws_eks_cluster.this.version}/${local.karpenter_ami_arch}/latest/image_id"
- After completing all these configuration changes, proceed to deploy the cluster.
Note: The additional requirements update the Terraform configuration files for the bootstrap script. Do not modify the
03_node_group/variables.tfor05_helm_releases/main.tffiles in the preceding installation steps. Reverting those changes will result in a secure cluster being deployed instead of a standard cluster.
Feedback
Was this page helpful?