# Terraform installation

This topic describes how to add and configure P0's Kubernetes integration for AWS EKS clusters using the [P0 Terraform provider](https://registry.terraform.io/providers/p0-security/p0/latest/docs).

{% hint style="info" %}
Use the P0 Terraform provider to configure integrations programmatically.

[Check the provider documentation here](https://registry.terraform.io/providers/p0-security/p0/latest/docs).

For more information, see the [P0 Terraform Provider documentation](https://github.com/p0-security/terraform-provider-p0).
{% endhint %}

* [Prerequisites](#prerequisites)
* [Overview](#overview)
* [Step 1: Stage the Kubernetes Integration](#step-1-stage-the-kubernetes-integration)
* [Step 2: Deploy the Admission Controller](#step-2-deploy-the-admission-controller)
* [Step 3: Complete the Installation](#step-3-finalize-the-installation)
* [Full Example](#full-example)
* [Resource Reference](#resource-reference)

## Prerequisites

Ensure you have the following before continuing:

* An existing Amazon Web Services (AWS) account with an [EKS cluster](https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html)
* The `cluster-admin` role in the target Kubernetes cluster
* [Terraform](https://developer.hashicorp.com/terraform/install) CLI installed
* [kubectl](https://kubernetes.io/docs/tasks/tools/) command-line tool
* The [P0 Terraform provider](https://registry.terraform.io/providers/p0-security/p0/latest/docs) configured in your Terraform project

{% hint style="info" %}
This resource currently only supports AWS EKS-based Kubernetes clusters.
{% endhint %}

## Overview

The Terraform-based installation uses a two-resource workflow:

1. **`p0_kubernetes_staged`** — Stages the integration by providing your cluster details. P0 generates PKI materials (CA bundle, server certificate, and private key) needed to deploy the admission controller.
2. **`p0_kubernetes`** — Finalizes the installation by providing the service account token and public JWK from the deployed admission controller back to P0.

The `p0_kubernetes` resource **must** be applied after `p0_kubernetes_staged`, because it depends on the PKI outputs generated during staging.

## Step 1: Stage the Kubernetes Integration

Use the `p0_kubernetes_staged` resource to register your EKS cluster with P0 and generate the required PKI materials:

```terraform
resource "p0_kubernetes_staged" "my_cluster" {
  id                    = "my-eks-cluster"
  connectivity_type     = "proxy"
  hosting_type          = "aws"
  cluster_arn           = "arn:aws:eks:us-west-2:123456789012:cluster/my-eks-cluster"
  cluster_endpoint      = "https://ABCDEF1234567890.gr7.us-west-2.eks.amazonaws.com"
  certificate_authority = "LS0tLS1CRUdJTi..."
}
```

### Inputs

| Attribute               | Description                                                                                                                       |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `id`                    | The EKS cluster name                                                                                                              |
| `connectivity_type`     | The connectivity type for the cluster: `public` (direct Internet access) or `proxy` (P0 reverse HTTPS proxy for private networks) |
| `hosting_type`          | The hosting type for the cluster (for example, `aws`)                                                                             |
| `cluster_arn`           | The ARN of the EKS cluster                                                                                                        |
| `cluster_endpoint`      | The EKS API server endpoint URL                                                                                                   |
| `certificate_authority` | The base-64 encoded certificate authority for the cluster                                                                         |

### Outputs

After applying, this resource exposes the following computed attributes:

| Attribute     | Description                                                             |
| ------------- | ----------------------------------------------------------------------- |
| `ca_bundle`   | The generated certificate authority bundle for the admission controller |
| `server_cert` | The generated certificate for the admission controller                  |
| `server_key`  | The generated private key for the admission controller                  |

{% hint style="info" %}
You can find the `cluster_endpoint` and `certificate_authority` values in the AWS EKS console under your cluster's **Overview** tab, or by running:

```bash
aws eks describe-cluster --name my-eks-cluster \
  --query 'cluster.{endpoint: endpoint, ca: certificateAuthority.data}'
```

{% endhint %}

## Step 2: Deploy the Admission Controller

After staging, use the PKI outputs from `p0_kubernetes_staged` to deploy P0's admission controller to your Kubernetes cluster. This step occurs outside of the P0 Terraform provider (for example, using the `kubernetes` or `helm` Terraform providers, or `kubectl`).

The admission controller deployment requires the following values from the staged resource:

* `p0_kubernetes_staged.my_cluster.ca_bundle`
* `p0_kubernetes_staged.my_cluster.server_cert`
* `p0_kubernetes_staged.my_cluster.server_key`

{% hint style="warning" %}
You must deploy the admission controller and retrieve the service account token and public JWK **before** applying the `p0_kubernetes` resource.
{% endhint %}

{% hint style="info" %}
If you chose the `proxy` connectivity type, the system creates an additional deployment called *braekhus*, which acts as a proxy between P0 and the Kubernetes control plane. For more information, see the [braekhus GitHub repo](https://github.com/p0-security/braekhus).
{% endhint %}

## Step 3: Complete the Installation

Use the `p0_kubernetes` resource to complete the installation by providing the service account credentials from your deployed admission controller:

```terraform
resource "p0_kubernetes" "my_cluster" {
  id         = p0_kubernetes_staged.my_cluster.id
  token      = var.p0_service_account_token
  public_jwk = var.p0_public_jwk

  connectivity_type     = "proxy"
  hosting_type          = "aws"
  cluster_arn           = "arn:aws:eks:us-west-2:123456789012:cluster/my-eks-cluster"
  cluster_endpoint      = "https://ABCDEF1234567890.gr7.us-west-2.eks.amazonaws.com"
  certificate_authority = "LS0tLS1CRUdJTi..."
}
```

### Inputs

| Attribute               | Description                                                             |
| ----------------------- | ----------------------------------------------------------------------- |
| `id`                    | The EKS cluster name (should match the `p0_kubernetes_staged` resource) |
| `token`                 | The value of the `p0-service-account-secret` (sensitive, write-only)    |
| `public_jwk`            | The public JWK token of the Braekhus service                            |
| `connectivity_type`     | The connectivity type for the cluster: `public` or `proxy`              |
| `hosting_type`          | The hosting type for the cluster (for example, `aws`)                   |
| `cluster_arn`           | The ARN of the EKS cluster                                              |
| `cluster_endpoint`      | The EKS API server endpoint URL                                         |
| `certificate_authority` | The base-64 encoded certificate authority for the cluster               |

### Outputs

| Attribute | Description                                                                                                |
| --------- | ---------------------------------------------------------------------------------------------------------- |
| `state`   | The install progress: `stage` (staged), `configure` (ready to configure), or `installed` (fully installed) |

{% hint style="info" %}
The `token` attribute is sensitive. Terraform does not display its value in plan output or state file exports. Consider using a secrets manager or Terraform variables to give this value.
{% endhint %}

## Full Example

The following example shows the complete two-step workflow:

```terraform
# Step 1: Stage the integration and generate PKI materials
resource "p0_kubernetes_staged" "my_cluster" {
  id                    = "my-eks-cluster"
  connectivity_type     = "proxy"
  hosting_type          = "aws"
  cluster_arn           = "arn:aws:eks:us-west-2:123456789012:cluster/my-eks-cluster"
  cluster_endpoint      = "https://ABCDEF1234567890.gr7.us-west-2.eks.amazonaws.com"
  certificate_authority = "LS0tLS1CRUdJTi..."
}

# Step 2: After deploying the admission controller using the PKI outputs above,
# finalize the installation with the service account credentials.
resource "p0_kubernetes" "my_cluster" {
  id         = p0_kubernetes_staged.my_cluster.id
  token      = var.p0_service_account_token
  public_jwk = var.p0_public_jwk

  connectivity_type     = p0_kubernetes_staged.my_cluster.connectivity_type
  hosting_type          = "aws"
  cluster_arn           = "arn:aws:eks:us-west-2:123456789012:cluster/my-eks-cluster"
  cluster_endpoint      = p0_kubernetes_staged.my_cluster.cluster_endpoint
  certificate_authority = p0_kubernetes_staged.my_cluster.certificate_authority
}

variable "p0_service_account_token" {
  type      = string
  sensitive = true
}

variable "p0_public_jwk" {
  type = string
}
```

{% hint style="success" %}
Once the `p0_kubernetes` resource reaches the `installed` state, your EKS cluster is fully integrated with P0 and users can make access requests to it. See [Requesting Access](/integrations/resource-integrations/kubernetes/requesting-access.md) for more information.
{% endhint %}

## Resource Reference

For detailed schema documentation, see the Terraform Registry:

* [`p0_kubernetes_staged`](https://registry.terraform.io/providers/p0-security/p0/latest/docs/resources/kubernetes_staged)
* [`p0_kubernetes`](https://registry.terraform.io/providers/p0-security/p0/latest/docs/resources/kubernetes)

For more information, see the [P0 Terraform Provider documentation](https://github.com/p0-security/terraform-provider-p0).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.p0.dev/integrations/resource-integrations/kubernetes/terraform-installation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
