# 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](https://docs.p0.dev/integrations/resource-integrations/kubernetes/requesting-access) 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).
