AWS permissions for provisioning
adj cluster provision runs an OpenTofu apply in your AWS account
(VPC + EKS + FSx for OpenZFS + the IAM roles/IRSA the cluster needs). This
page is the policy to grant the principal that runs it.
Print the same document locally — no login, no cluster, works offline:
$ adj cluster iam-policy
The policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Networking",
"Effect": "Allow",
"Action": [
"ec2:CreateVpc",
"ec2:DeleteVpc",
"ec2:DescribeVpcs",
"ec2:CreateSubnet",
"ec2:CreateRouteTable",
"ec2:CreateInternetGateway",
"ec2:CreateNatGateway",
"ec2:AllocateAddress",
"ec2:CreateSecurityGroup",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RunInstances",
"ec2:CreateTags"
],
"Resource": "*"
},
{
"Sid": "EKS",
"Effect": "Allow",
"Action": [
"eks:CreateCluster",
"eks:DescribeCluster",
"eks:DeleteCluster",
"eks:CreateNodegroup",
"eks:DescribeNodegroup",
"eks:TagResource"
],
"Resource": "*"
},
{
"Sid": "FSxOpenZFS",
"Effect": "Allow",
"Action": [
"fsx:CreateFileSystem",
"fsx:DescribeFileSystems",
"fsx:DeleteFileSystem",
"fsx:CreateVolume",
"fsx:DeleteVolume",
"fsx:TagResource"
],
"Resource": "*"
},
{
"Sid": "IAM",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:PassRole",
"iam:CreatePolicy",
"iam:CreateOpenIDConnectProvider",
"iam:TagRole"
],
"Resource": "*"
}
]
}
This is the representative action set the provisioning preflight
simulates (with iam:SimulatePrincipalPolicy) before touching any
resource. It is representative, not exhaustive — the module also exercises
further read/describe/tag calls within these same services during an apply,
so the practical grant is "administrative access to EC2, EKS, FSx, and IAM
role management". Resource is "*" because the resources the module
creates do not exist (and have no ARNs) until apply time.
What the preflight checks
Before rotating the join token or creating anything, adj cluster provision:
- Resolves credentials (
--aws-profile, or ambientAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY) and callssts get-caller-identity. - Probes IAM capability with one read-only call. Provisioning must create IAM roles, so credentials that cannot call IAM at all are rejected immediately (see below) instead of failing ten minutes into the apply with VPC/NAT/FSx already billing.
- Simulates the action set above against your principal and hard-fails
with the exact missing actions if any are denied. If the simulation
itself cannot run (the principal lacks
iam:SimulatePrincipalPolicy, or is not simulatable), provisioning proceeds with a warning — only a known gap blocks.
STS session tokens do not work
Credentials from aws sts get-session-token cannot call any IAM API
(without MFA) — an AWS limitation, not a policy problem. They pass the
identity check, but provisioning creates IAM roles, so the apply would fail
at the first role with:
InvalidClientTokenId: The security token included in the request is invalid
The preflight now detects exactly this and refuses up front. Use one of:
- permanent access keys for an IAM user holding the policy above,
- an assumed role (
aws sts assume-role, or a profile withrole_arn), or - AWS SSO (
aws sso login).