Skip to content

Kubernetes

The manifests in deploy/kubernetes/ run the dashboard as one pod, with a service account that maps to an IAM role on EKS. The manifests are the source of truth; this page explains them.

kubectl apply -f deploy/kubernetes/

Before applying, replace the image tag if you want another release, and the role ARN in serviceaccount.yaml. Apply into the namespace you want; the trust policy of the role must name that namespace (below).

The three manifests

serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: vpcatlas
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/vpcatlas-auditor
automountServiceAccountToken: false

The eks.amazonaws.com/role-arn annotation is IAM roles for service accounts (IRSA): EKS injects a web identity token and the SDK exchanges it for the role's credentials. No access keys are involved. The service account token for the Kubernetes API is not mounted, because the dashboard never talks to the cluster.

deployment.yaml

One replica of vpcatlas/vpcatlas:0.1.0, listening on 8080:

  • The pod runs as non-root (runAsUser and runAsGroup 10001), with the RuntimeDefault seccomp profile; the container drops all capabilities, forbids privilege escalation and has a read-only root file system with an emptyDir of 256 MiB at /tmp.
  • Resources: requests 100m CPU and 256Mi; limits 1 CPU and 1Gi.
  • readinessProbe and livenessProbe request /healthz on the http port.
  • The image's default command serves the dashboard, so the file sets no command.
  • Environment:
Variable Value in the file Meaning
VPCATLAS_REFRESH_SECONDS "900" Seconds between scans (minimum 300). 0 scans only at start-up and on Refresh now.
VPCATLAS_REGIONS "all" Comma separated Regions, or all for every Region enabled in the account.
VPCATLAS_AUTH_PASSWORD from the Secret vpcatlas-auth, key password (optional: true) HTTP Basic protection. If the Secret does not exist, the dashboard starts open.
VPCATLAS_ROLE_ARN, VPCATLAS_EXTERNAL_ID commented out Role to assume in another account, and its external id.

Create the password Secret before the Deployment:

kubectl create secret generic vpcatlas-auth --from-literal=password='a-long-random-password'

service.yaml

A ClusterIP service on port 8080. The dashboard shows your network topology, so reach it through a private ingress, a VPN, or a port-forward, not a public load balancer:

kubectl port-forward svc/vpcatlas 8080:8080

If you put an ingress in front, terminate TLS there, and set VPCATLAS_BASE_PATH when it serves the dashboard under a path (see the dashboard page).

The IAM role

Create the role vpcatlas-auditor with:

  1. Permissions: the auditor policy deploy/iam/auditor-policy.json (also printed by vpcatlas iam-policy), or the managed ReadOnlyAccess.
  2. A trust policy for the cluster's OIDC provider that allows system:serviceaccount:<namespace>:vpcatlas, where <namespace> is the namespace you apply the files into. The usual form, with your cluster's OIDC provider id:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE" },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:default:vpcatlas",
          "oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
        }
      }
    }
  ]
}

This block is the standard IRSA trust policy, not a file in the repository; adapt the account id, the Region, the provider id and the namespace.

To audit other accounts, give this role sts:AssumeRole on their auditor roles and set VPCATLAS_ROLE_ARN (comma separated) in the Deployment, plus VPCATLAS_EXTERNAL_ID if their trust policies require one. The trust policy for those roles is in iam.md. Outside EKS, remove the annotation and give the pod credentials some other way; the standard chain applies (see docker.md).

Snapshot storage and replicas

The Deployment has one replica because the snapshot is kept in the memory of the pod. Several replicas would each scan on their own and, with a shared VPCATLAS_SNAPSHOT_URI, would also write the same history keys. To keep the history across restarts, set VPCATLAS_SNAPSHOT_URI=s3://bucket/prefix and add to the role:

  • s3:GetObject, s3:PutObject, s3:DeleteObject on arn:aws:s3:::bucket/prefix/*;
  • s3:ListBucket on arn:aws:s3:::bucket with the condition s3:prefix = prefix/*.

A file:/// location also works if you mount a writable volume there (the root file system is read-only). The keys written are in the dashboard page.