Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt

Use this file to discover all available pages before exploring further.

Phase 2 adds Node Pools and DFS volumes on top of the VPC and CKS cluster from Phase 1. These resources are Kubernetes manifests that require a running cluster and kubeconfig. This guide also covers the following optional configurations:
  • Object Storage
  • OIDC Workload Identity Federation for Object Storage (instead of static CoreWeave API keys)

Prerequisites

Node Pools and DFS volumes

Node pools and DFS PVCs are managed as Kubernetes manifests, so Terraform needs the kubeconfig you downloaded at the end of Phase 1.
Your CoreWeave user or API token must have the CKS Admin IAM role. See the prerequisites.

Configuration

In this section, you’ll set the kubeconfig path and enable Node Pools and DFS volumes.

Set the kubeconfig path

In terraform.tfvars, set the path to the kubeconfig you downloaded at the end of Phase 1:
cks_kubeconfig_path = "[PATH-TO-DOWNLOADED-KUBECONFIG]"

Enable node pools and DFS

To enable Node Pools and DFS volumes, set the following variables in your terraform.tfvars file:
create_nodepool = true
create_dfs_pvc  = true

Create and verify your Node Pools and DFS volumes

In this section, you’ll apply your Terraform configuration to create your Node Pools and DFS volumes.

Apply your Terraform configuration

Run the following commands to plan your changes and apply your changes to enable Node Pools and DFS volumes:
terraform plan
terraform apply

Verify outputs

After terraform apply completes, verify the outputs to ensure your Node Pools and DFS volumes were created successfully:
terraform output nodepools
terraform output dfs_pvcs

Add Object Storage (optional)

The Object Storage module is an optional add-on that creates an AI Object Storage bucket with organization-level and optional bucket-level access policies. Object Storage resources do not require kubeconfig and can be included in either Phase 1 or Phase 2.
Your user or API token must have the Object Storage Admin IAM role. See the prerequisites.

Configure object storage access policies

In this section, you’ll configure the object storage access policies for your Object Storage bucket. You need at least one organization access policy before creating buckets; bucket access policies are optional. The following policies are available in your terraform.tfvars file (copied from the terraform.tfvars.example file) as examples; edit them to suit your needs.

Organization access policies

The object_storage_org_access_policies variable is a map (key = policy name), so you can create multiple policies for different concerns. At least one organization access policy must exist before creating buckets.
Open access (single policy)
A single policy granting full S3 and Object Storage API access to every principal in the organization. Suitable for dev/test environments or single-team setups where all users share the same level of access:
object_storage_org_access_policies = {
  "open-access" = {
    statements = [
      {
        name       = "allow-all-principals-full-access"
        effect     = "Allow"
        actions    = ["s3:*", "cwobject:*"]
        resources  = ["*"]
        principals = ["*"]
      }
    ]
  }
}
Scoped access (multiple policies)
Separate policies for different access patterns with named principals, least-privilege actions, independently manageable and auditable:
object_storage_org_access_policies = {
  "admin-access" = {
    statements = [
      {
        name       = "allow-admin-full-access"
        effect     = "Allow"
        actions    = ["s3:*", "cwobject:*"]
        resources  = ["*"]
        principals = ["admin@example.com", "platform-team@example.com"]
      }
    ]
  }

  "oidc-wif" = {
    statements = [
      {
        name       = "allow-oidc-key-creation"
        effect     = "Allow"
        actions    = ["cwobject:CreateAccessKeyOIDC"]
        resources  = ["*"]
        principals = ["role/https://idp.example.com:svc-data-ingest"]
      },
      {
        name       = "allow-s3-rw-training-bucket"
        effect     = "Allow"
        actions    = ["s3:GetObject", "s3:PutObject", "s3:ListBucket", "s3:DeleteObject"]
        resources  = ["training-data", "training-data/*"]
        principals = ["role/https://idp.example.com:svc-data-ingest"]
      }
    ]
  }
}

Bucket access policies (optional)

Bucket access policies add fine-grained, S3-compatible access control for a single bucket. They are evaluated after organization access policies. Managed with the object_storage_bucket_policy_statements variable.
object_storage_bucket_policy_statements = [
  {
    sid    = "allow-read-oidc-role"
    effect = "Allow"
    actions   = ["s3:GetObject", "s3:ListBucket"]
    resources = ["arn:aws:s3:::[BUCKET-NAME]", "arn:aws:s3:::[BUCKET-NAME]/*"]
    principals = {
      "CW" = ["arn:aws:iam::[ORG-CLOUD-ID]:role/https://idp.example.com:svc-reader"]
    }
  }
]
Key difference: Organization policies use short-form principals (for example, role/https://idp.example.com:sub), while bucket policies use full ARNs (for example, arn:aws:iam::<org-id>:role/https://idp.example.com:sub).

Create a bucket

  1. Set the bucket variables in terraform.tfvars:
    object_storage_bucket_name = "[BUCKET-NAME]"
    
    Bucket names must be globally unique, and adhere to the following rules:
    • Length: 3 to 63 characters.
    • Characters: Only lowercase letters (a-z), numbers (0-9), and hyphens (-). No dots, uppercase letters, underscores, spaces, or other special characters.
    • Start and end: Must begin and end with a letter or number. Cannot start or end with a hyphen (-).
    • Prohibited patterns: Cannot start with xn--.- Reserved: Must not begin with cw-, vip-, or log-stitcher-ch-. Must not be the exact name int. These are reserved for internal use.
  2. Run the following commands to plan your changes and apply your changes to create your Object Storage bucket:
    terraform plan
    terraform apply
    
  3. After terraform apply completes, verify the outputs to ensure your Object Storage bucket was created successfully:
    terraform output object_storage_bucket_name
    terraform output object_storage_org_access_policy_names
    
For full resource documentation, see the Terraform provider reference for organization access policies, buckets, and bucket policies.

OIDC Workload Identity Federation for Object Storage

For production environments, OIDC Workload Identity Federation (WIF) eliminates static API keys by exchanging short-lived JWT tokens from your identity provider for temporary Object Storage credentials. CKS clusters expose an OIDC issuer URL for Kubernetes service account tokens. After Phase 1 completes, retrieve this URL from the Terraform output:
terraform output cks_service_account_oidc_issuer_url
You can use this URL as the issuer when creating a WIF configuration in the Console, allowing CKS workloads to access Object Storage without static credentials. The derived role identity follows this format:
role/<cks_service_account_oidc_issuer_url>:system:serviceaccount:<namespace>:<sa-name>
Grant that role access in your organization access policy (see the “Scoped access” example above for the Terraform syntax).
Creating a WIF configuration requires the IAM Admin role. There is no Terraform resource for WIF configurations today; create them in Console > Organization > IAM > Workload Federation.
For the complete WIF setup walkthrough, including OIDC provider configuration, required JWT claims, environment variable setup, and troubleshooting, see Using Workload Identity Federation with OIDC. For background on how WIF works, see Workload Identity Federation for AI Object Storage.

Migrating from an older repository layout

If you previously had object_storage.tf, nodepool.tf, or dfs.tf at the root level and are updating to the module layout, Terraform will plan to destroy and recreate those resources unless you move state. Run the following commands once after pulling the new layout:
terraform state mv 'coreweave_object_storage_bucket.main[0]' \
  'module.object_storage.coreweave_object_storage_bucket.main[0]' 2>/dev/null || true

terraform state mv 'kubernetes_manifest.nodepool_example[0]' \
  'module.nodepool["example-nodepool"].kubernetes_manifest.nodepool' 2>/dev/null || true

terraform state mv 'kubernetes_manifest.dfs_pvc[0]' \
  'module.dfs["dfs-shared"].kubernetes_manifest.pvc' 2>/dev/null || true
Omit any line for resources not in your state. Then run terraform plan to confirm no changes for those resources.

Next steps

Last modified on April 20, 2026