Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions aws-integration-setup/terraform-v6/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Nullify AWS Integration Terraform (AWS Provider v6)

This directory mirrors `../terraform/` but targets **AWS Terraform provider v6** (`~> 6.0`). Use this if your project has already upgraded to AWS provider v6.

For AWS provider v5, use `../terraform/` instead.

## What Changed from v5

The only breaking change that affects this configuration:

**`data "aws_eks_cluster_auth"` was removed in AWS provider v6.** It is replaced by the `ephemeral` resource variant, which requires Terraform >= 1.10:

```hcl
# v5 (removed in v6)
data "aws_eks_cluster_auth" "primary" {
name = "..."
}
token = data.aws_eks_cluster_auth.primary.token

# v6
ephemeral "aws_eks_cluster_auth" "primary" {
name = "..."
}
token = ephemeral.aws_eks_cluster_auth.primary.token
```

This change is applied in `examples/multi-cluster-complete/main.tf`. The core `nullify-aws-integration` module and `k8s-resources` module are unaffected.

## Requirements

- Terraform >= 1.10 (for ephemeral resource support in the multi-cluster example)
- AWS provider ~> 6.0
- Kubernetes provider ~> 2.20

## Architecture

```
terraform-v6/
├── modules/
│ ├── nullify-aws-integration/ # AWS IAM resources only
│ │ ├── versions.tf # AWS provider ~> 6.0
│ │ ├── variables.tf
│ │ ├── locals.tf
│ │ ├── data.tf
│ │ ├── main.tf
│ │ └── outputs.tf
│ └── k8s-resources/ # Kubernetes resources only
│ ├── providers.tf
│ ├── variables.tf
│ ├── main.tf
│ └── outputs.tf
├── examples/
│ ├── basic/ # AWS IAM only example
│ └── multi-cluster-complete/ # Full multi-cluster EKS example
├── versions.tf # AWS ~> 6.0, Kubernetes ~> 2.20
├── variables.tf
├── main.tf
├── outputs.tf
├── providers.tf
├── terraform.tfvars.example
└── README.md
```

## Quick Start

### 1. AWS-Only Integration

```bash
cd examples/basic/
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with your values
terraform init && terraform apply
```

### 2. Multi-Cluster EKS Integration

```bash
cd examples/multi-cluster-complete/
cp terraform.tfvars.example terraform.tfvars
# Edit with your cluster ARNs and values
terraform init && terraform apply
```

## Required Variables

- `customer_name`: Your company/customer name (used in resource naming)
- `external_id`: External ID for cross-account access (provided by Nullify configure page)
- `nullify_role_arn`: Nullify's cross-account role ARN (provided by Nullify configure page)

## Optional Variables

- `aws_region`: AWS region for IAM resources (default: ap-southeast-2)
- `s3_bucket_name`: S3 bucket for scan results (optional)
- `kms_key_arn`: KMS key ARN for key management operations (optional)
- `enable_kubernetes_integration`: Set to `true` for EKS integration
- `eks_cluster_arns`: List of EKS cluster ARNs to integrate with
- `kubernetes_namespace`: Kubernetes namespace name (default: nullify)
- `cronjob_schedule`: Cron schedule for data collection (default: "0 0 * * *")
- `collector_image`: Docker image for collector (default: nullify/k8s-collector:latest)
- `tags`: Resource tags

## Validation

```bash
terraform fmt -recursive
terraform validate
terraform plan
```
47 changes: 47 additions & 0 deletions aws-integration-setup/terraform-v6/examples/basic/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Basic Example: Nullify AWS Integration (AWS resources only)
# This example shows the minimal setup for AWS integration without Kubernetes

terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}

provider "aws" {
region = var.aws_region
}

module "nullify_aws_integration" {
source = "../../modules/nullify-aws-integration"

# Required variables
customer_name = var.customer_name
external_id = var.external_id
nullify_role_arn = var.nullify_role_arn

# AWS Configuration
aws_region = var.aws_region
s3_bucket_name = var.s3_bucket_name
kms_key_arn = var.kms_key_arn

# Kubernetes integration disabled - no Kubernetes provider needed
enable_kubernetes_integration = false

# Custom tags
tags = var.tags
}

output "role_arn" {
description = "ARN of the created IAM role"
value = module.nullify_aws_integration.role_arn
}

output "deployment_summary" {
description = "Summary of the deployment"
value = module.nullify_aws_integration.deployment_summary
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Basic Example - AWS-only integration (no Kubernetes)
# Copy this file to terraform.tfvars and fill in your values.

# REQUIRED: Customer name (provided by Nullify)
customer_name = "acme-corp"

# REQUIRED: External ID for cross-account role assumption (provided by Nullify)
external_id = "your-external-id-from-nullify"

# REQUIRED: Nullify cross-account role ARN (provided by Nullify)
nullify_role_arn = "arn:aws:iam::123456789012:role/NullifyRole"

# AWS region where resources are deployed
aws_region = "ap-southeast-2"

# S3 bucket name for storing scan results (optional, provided by Nullify if needed)
# s3_bucket_name = "nullify-scan-results-acme-corp"

# KMS key ARN for encryption (optional, provided by Nullify if needed)
# kms_key_arn = "arn:aws:kms:ap-southeast-2:123456789012:key/12345678-1234-1234-1234-123456789012"

# Tags to apply to all AWS resources
tags = {
Environment = "production"
Team = "security"
Project = "nullify-integration"
ManagedBy = "Terraform"
}
49 changes: 49 additions & 0 deletions aws-integration-setup/terraform-v6/examples/basic/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
variable "customer_name" {
type = string
description = "The name of the customer to create the role for"
default = "acme-corp"

validation {
condition = can(regex("^[a-zA-Z][a-zA-Z0-9_-]*$", var.customer_name))
error_message = "Customer name must start with a letter and can only contain letters, numbers, underscores, and hyphens"
}
}

variable "external_id" {
type = string
description = "The external ID for the role (provided by Nullify)"
}

variable "nullify_role_arn" {
type = string
description = "The Nullify cross-account role ARN"
}

variable "aws_region" {
type = string
description = "The AWS region where resources are deployed"
default = "ap-southeast-2"
}

variable "s3_bucket_name" {
type = string
description = "The name of the S3 bucket for storing scan results (optional)"
default = ""
}

variable "tags" {
type = map(string)
description = "Tags to apply to AWS resources"
default = {
Environment = "production"
Team = "security"
Project = "nullify-integration"
ManagedBy = "Terraform"
}
}

variable "kms_key_arn" {
type = string
description = "The ARN of the KMS key for key management operations (optional, provided by Nullify if needed)"
default = ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
terraform {
required_version = ">= 1.10"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.20"
}
}
}

provider "aws" {
region = var.aws_region
}

data "aws_eks_cluster" "primary" {
name = element(split("/", var.eks_cluster_arns[0]), length(split("/", var.eks_cluster_arns[0])) - 1)
}

# aws_eks_cluster_auth was removed as a data source in AWS provider v6.
# Use the ephemeral resource instead (requires Terraform >= 1.10).
ephemeral "aws_eks_cluster_auth" "primary" {
name = element(split("/", var.eks_cluster_arns[0]), length(split("/", var.eks_cluster_arns[0])) - 1)
}

data "aws_eks_cluster" "secondary" {
name = element(split("/", var.eks_cluster_arns[1]), length(split("/", var.eks_cluster_arns[1])) - 1)
}

ephemeral "aws_eks_cluster_auth" "secondary" {
name = element(split("/", var.eks_cluster_arns[1]), length(split("/", var.eks_cluster_arns[1])) - 1)
}

provider "kubernetes" {
alias = "primary"
host = data.aws_eks_cluster.primary.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.primary.certificate_authority[0].data)
token = ephemeral.aws_eks_cluster_auth.primary.token
}

provider "kubernetes" {
alias = "secondary"
host = data.aws_eks_cluster.secondary.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.secondary.certificate_authority[0].data)
token = ephemeral.aws_eks_cluster_auth.secondary.token
}

module "nullify_aws_integration" {
source = "../../modules/nullify-aws-integration"
customer_name = var.customer_name
external_id = var.external_id
nullify_role_arn = var.nullify_role_arn
aws_region = var.aws_region
s3_bucket_name = var.s3_bucket_name
kms_key_arn = var.kms_key_arn

# Multiple Kubernetes Clusters Configuration
enable_kubernetes_integration = true
eks_cluster_arns = var.eks_cluster_arns
kubernetes_namespace = var.kubernetes_namespace
tags = var.tags
}

module "k8s_resources_primary" {
source = "../../modules/k8s-resources"
providers = {
kubernetes = kubernetes.primary
}
iam_role_arn = module.nullify_aws_integration.role_arn
s3_bucket_name = var.s3_bucket_name
kms_key_arn = var.kms_key_arn
aws_region = var.aws_region
kubernetes_namespace = var.kubernetes_namespace
cronjob_schedule = var.cronjob_schedule
collector_image = var.collector_image
}

module "k8s_resources_secondary" {
source = "../../modules/k8s-resources"
providers = {
kubernetes = kubernetes.secondary
}
iam_role_arn = module.nullify_aws_integration.role_arn
s3_bucket_name = var.s3_bucket_name
kms_key_arn = var.kms_key_arn
aws_region = var.aws_region
kubernetes_namespace = var.kubernetes_namespace
cronjob_schedule = var.cronjob_schedule
collector_image = var.collector_image
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# AWS Integration Outputs
output "iam_role_arn" {
description = "ARN of the IAM Role with cross-account read access"
value = module.nullify_aws_integration.role_arn
}

output "deployment_summary" {
description = "Summary of the complete Nullify integration deployment"
value = module.nullify_aws_integration.deployment_summary
}

output "cluster_integration_summary" {
description = "Summary of all cluster integrations"
value = module.nullify_aws_integration.cluster_integration_summary
}

# Kubernetes Resources
output "k8s_resources_primary" {
description = "Kubernetes resources deployed to primary cluster"
value = {
namespace_name = module.k8s_resources_primary.namespace_name
service_account_name = module.k8s_resources_primary.service_account_name
cluster_role_name = module.k8s_resources_primary.cluster_role_name
cluster_role_binding_name = module.k8s_resources_primary.cluster_role_binding_name
cronjob_name = module.k8s_resources_primary.cronjob_name
}
}

output "k8s_resources_secondary" {
description = "Kubernetes resources deployed to secondary cluster"
value = {
namespace_name = module.k8s_resources_secondary.namespace_name
service_account_name = module.k8s_resources_secondary.service_account_name
cluster_role_name = module.k8s_resources_secondary.cluster_role_name
cluster_role_binding_name = module.k8s_resources_secondary.cluster_role_binding_name
cronjob_name = module.k8s_resources_secondary.cronjob_name
}
}
Loading
Loading