Skip to content

Commit

Permalink
Initial
Browse files Browse the repository at this point in the history
  • Loading branch information
mthorley committed Jan 26, 2020
0 parents commit b3fc0c5
Show file tree
Hide file tree
Showing 13 changed files with 419 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# gke-tf
6 changes: 6 additions & 0 deletions inspec-exec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@


/opt/terraform plan -out tf.out
/opt/terraform show -json tf.out > tf.json
mv tf.json pac/files
inspec exec pac
146 changes: 146 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@

resource "google_container_cluster" "cluster" {
provider = google

name = var.cluster_name
project = var.project
location = var.region

//network = google_compute_network.network.self_link
//subnetwork = google_compute_subnetwork.subnetwork.self_link

logging_service = "logging.googleapis.com/kubernetes"
monitoring_service = "monitoring.googleapis.com/kubernetes"

// Decouple the default node pool lifecycle from the cluster object lifecycle
// by removing the node pool and specifying a dedicated node pool in a
// separate resource below.
remove_default_node_pool = "true"
initial_node_count = 1

// Configure various addons
addons_config {
// Disable the Kubernetes dashboard, which is often an attack vector. The
// cluster can still be managed via the GKE UI.
kubernetes_dashboard {
disabled = true
}

// Enable network policy (Calico)
network_policy_config {
disabled = false
}
}

// Enable workload identity
// workload_identity_config {
// identity_namespace = format("%s.svc.id.goog", var.project)
// }

// Disable basic authentication and cert-based authentication.
// Empty fields for username and password are how to "disable" the
// credentials from being generated.
master_auth {
username = ""
password = ""

client_certificate_config {
issue_client_certificate = "false"
}
}

// Enable network policy configurations (like Calico) - for some reason this
// has to be in here twice.
network_policy {
enabled = "true"
}

// Allocate IPs in our subnetwork
ip_allocation_policy {
use_ip_aliases = true
// cluster_secondary_range_name = google_compute_subnetwork.subnetwork.secondary_ip_range.0.range_name
// services_secondary_range_name = google_compute_subnetwork.subnetwork.secondary_ip_range.1.range_name
}

// Specify the list of CIDRs which can access the master's API
master_authorized_networks_config {
cidr_blocks {
display_name = "homeoffice"
cidr_block = "144.132.96.146/32"
}
}
// Configure the cluster to have private nodes and private control plane access only
private_cluster_config {
enable_private_endpoint = "true"
enable_private_nodes = "true"
master_ipv4_cidr_block = "172.16.0.16/28"
}

// Allow plenty of time for each operation to finish (default was 10m)
timeouts {
create = "30m"
update = "30m"
delete = "30m"
}

}

// A dedicated/separate node pool where workloads will run. A regional node pool
// will have "node_count" nodes per zone, and will use 3 zones. This node pool
// will be 3 nodes in size and use a non-default service-account with minimal
// Oauth scope permissions.
resource "google_container_node_pool" "private-np-1" {
provider = google-beta

name = "private-np-1"
location = var.region
cluster = google_container_cluster.cluster.name
node_count = "1"

// Repair any issues but don't auto upgrade node versions
management {
auto_repair = "true"
auto_upgrade = "false"
}

node_config {
machine_type = "n1-standard-2"
disk_type = "pd-ssd"
disk_size_gb = 30
image_type = "COS"

// Use the cluster created service account for this node pool
//service_account = google_service_account.gke-sa.email

// Use the minimal oauth scopes needed
oauth_scopes = [
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring",
"https://www.googleapis.com/auth/servicecontrol",
"https://www.googleapis.com/auth/service.management.readonly",
"https://www.googleapis.com/auth/trace.append",
]

labels = {
cluster = "${var.cluster_name}"
}

// Enable workload identity on this node pool
workload_metadata_config {
node_metadata = "GKE_METADATA_SERVER"
}

metadata = {
// Set metadata on the VM to supply more entropy
google-compute-enable-virtio-rng = "true"
// Explicitly remove GCE legacy metadata API endpoint
disable-legacy-endpoints = "true"
}
}

depends_on = [
google_container_cluster.cluster,
]
}

50 changes: 50 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

// output variables used by inspec

output "gke_enable_legacy_abac" {
value = google_container_cluster.cluster.enable_legacy_abac
}

output "gke_location" {
value = google_container_cluster.cluster.location
}

output "gke_logging" {
value = google_container_cluster.cluster.logging_service
}

output "gke_monitoring" {
value = google_container_cluster.cluster.monitoring_service
}

output "gke_master_username" {
value = google_container_cluster.cluster.master_auth[0].username
}

output "gke_master_password" {
value = google_container_cluster.cluster.master_auth[0].password
}

output "gke_issue_client_cert" {
value = google_container_cluster.cluster.master_auth[0].client_certificate_config[0].issue_client_certificate
}

output "gke_network_policy" {
value = google_container_cluster.cluster.network_policy[0].enabled
}

output "gke_network_policy_config" {
value = google_container_cluster.cluster.addons_config[0].network_policy_config[0].disabled
}

output "gke_private_endpoint" {
value = google_container_cluster.cluster.private_cluster_config[0].enable_private_endpoint
}

output "gke_private_nodes" {
value = google_container_cluster.cluster.private_cluster_config[0].enable_private_nodes
}

output "gke_master_cidr_block" {
value = google_container_cluster.cluster.private_cluster_config[0].master_ipv4_cidr_block
}
2 changes: 2 additions & 0 deletions pac/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# GKE Terraform Config InSpec Profile

92 changes: 92 additions & 0 deletions pac/controls/gke.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# encoding: utf-8
# copyright: 2020 Matt Thorley

title 'GKE Terraform Unit Tests'

# verify format of terraform
control 'PL.TF.C-01' do
impact 1.0
title 'Confirm terraform format version'
desc 'Terraform json format version supported is 0.1'
describe gke_config do
its('version') { should eq '0.1' }
end
end

control 'PL.GKE.C-02' do
impact 1.0
title 'Legacy ABAC disabled'
desc 'Legacy ABAC is deprecated and must not be enabled - instead use RBAC.'
describe gke_config do
it { should_not have_legacy_abac_enabled }
end
end

control 'PL.GKE.C-03' do
impact 1.0
title 'Region containment to AU'
desc 'Region must be AU.'
describe gke_config do
its('location') { should eq 'australia-southeast1'}
end
end

control 'PL.GKE.C-04' do
impact 1.0
title 'GKE logging must be enabled'
desc 'GKE logging must be enabled.'
describe gke_config do
its('logging_service') { should eq 'logging.googleapis.com/kubernetes' }
end
end

control 'PL.GKE.C-05' do
impact 1.0
title 'GKE monitoring must be enabled'
desc 'GKE monitoring must be enabled.'
describe gke_config do
its('monitoring_service') { should eq 'monitoring.googleapis.com/kubernetes' }
end
end

control 'PL.GKE.C-06' do
impact 1.0
title 'GKE master basic authentication must be disabled and client cert must not be issued'
desc 'GKE master basic authentication username and password must be disabled.'
describe gke_config do
its('master_username') { should eq '' }
end
describe gke_config do
its('master_password') { should eq '' }
end
describe gke_config do
it { should_not have_issued_client_cert }
end
end

control 'PL.GKE.C-08' do
impact 1.0
title 'Network policy must be enabled'
desc 'Network policy must be enabled to control pod to pod communication.'
describe gke_config do
it { should have_network_policy_enabled }
end
describe gke_config do
it { should_not have_network_policy_config_disabled }
end
end

control 'PL.GKE.C-09' do
impact 1.0
title 'Ensure private nodes and private control plane access only'
desc 'Cluster must be have private endpoints, nodes and a specified master cidr.'
describe gke_config do
it { should have_a_private_endpoint }
end
describe gke_config do
it { should have_private_nodes }
end
describe gke_config do
its('master_cidr_block') { should_not be_empty }
end
end
Loading

0 comments on commit b3fc0c5

Please sign in to comment.