Unable to pull from GCR
mbaroody opened this issue · 1 comments
Question
First of all, thank you. This is an amazing reference.
I'm using a variation of your terraform scripts, and the service_account you have set up right now I don't believe allows for image pulling from a private repository. I've been trying all day to figure out which roles are required for that to be possible. My goal is to pull a vault-init image that my organization has built :)
Considerations
Here is a module which set's up the vault configuration on GCP. You can assume the rest is pretty much the same:
# main.tf
terraform {
required_version = "0.12.0"
}
resource "google_service_account" "default" {
account_id = "vault-admin-sa"
display_name = "Vault Server Admin"
project = "${var.project_id}"
}
# Create a service account key
resource "google_service_account_key" "default" {
service_account_id = "${google_service_account.default.name}"
}
resource "google_project_iam_member" "default" {
count = "${length(var.service_account_roles)}"
project = "${var.project_id}"
role = "${element(var.service_account_roles, count.index)}"
member = "serviceAccount:${google_service_account.default.email}"
}
resource "google_storage_bucket" "default" {
name = "${var.project_id}-vault-storage"
location = "${var.bucket_location}"
project = "${var.project_id}"
# In prod, the Storage Bucket should NEVER be emptied and deleted via Terraform unless you know exactly what you're doing.
# However, for testing purposes, it's often convenient to destroy a non-empty Storage Bucket.
force_destroy = "${var.bucket_force_destroy}"
storage_class = "${var.bucket_storage_class}"
versioning {
enabled = true
}
lifecycle_rule {
action {
type = "Delete"
}
condition {
num_newer_versions = 1
}
}
}
resource "google_storage_bucket_iam_member" "default" {
count = "${length(var.bucket_roles_for_service_account)}"
bucket = "${google_storage_bucket.default.name}"
role = "${element(var.bucket_roles_for_service_account, count.index)}"
member = "serviceAccount:${google_service_account.default.email}"
}
resource "google_kms_crypto_key_iam_member" "default" {
crypto_key_id = "${var.auto_unseal_key_project_id}/${var.auto_unseal_key_region}/${var.auto_unseal_keyring}/${var.auto_unseal_key_name}"
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:${google_service_account.default.email}"
}
# create external/internal load balancer!
resource "google_compute_address" "default" {
name = "vault-lb"
address_type = "${var.load_balancer_address_type}"
}
# variables.tf
variable "project_id" {
description = "The name of the GCP Project where all resources will be launched."
}
variable "subnetwork" {
description = "The name of the VPC Network where all resources should be created."
}
variable "auto_unseal_key_project_id" {
description = "project_id of auto unseal keyring"
}
variable "auto_unseal_key_region" {
description = "region of auto unseal keyring"
}
variable "auto_unseal_keyring" {
description = "keyring auto unseal name"
}
variable "auto_unseal_key_name" {
description = "key name"
}
variable "service_account_roles" {
description = "the service account of whatever will be running Vault (e.g. GKE or a VM)"
default = [
"roles/logging.logWriter",
"roles/monitoring.metricWriter",
"roles/monitoring.viewer",
]
}
variable "bucket_location" {
description = "The GCS location"
default = "US"
}
variable "bucket_storage_class" {
description = "The GCS location"
default = "MULTI_REGIONAL"
}
variable "bucket_roles_for_service_account" {
description = "roles to assign the service account regarding the bucket created"
type = "list"
default = [
"roles/storage.legacyBucketReader",
"roles/storage.objectAdmin",
]
}
variable "bucket_force_destroy" {
description = "When deleting a bucket, this boolean option will delete all contained objects. If you try to delete a bucket that contains objects, Terraform will fail that run."
default = false
}
variable "load_balancer_address_type" {
description = "address type of load balancer ('INTERNAL' or 'EXTERNAL')"
default = "INTERNAL"
}
I'm assuming this is just a simple addition to the variable service_account_roles
? Or perhaps creating a custom role of some sort? Here is the terraform that sets up a cluster (not hardened properly yet):
resource "google_container_cluster" "default" {
name = "${var.name}"
project = "${var.project_id}"
location = "${var.location}"
network = "${var.network}"
subnetwork = "${var.subnetwork}"
master_authorized_networks_config {
# TODO
cidr_blocks {
cidr_block = "0.0.0.0/0"
display_name = "all"
}
}
initial_node_count = "${var.initial_node_count}"
# min_master_version = "${data.google_container_engine_versions.default.latest_master_version}"
min_master_version = "${var.min_master_version}"
enable_legacy_abac = false
master_auth {
username = "${var.master_username}"
password = "${var.master_password}"
client_certificate_config {
issue_client_certificate = "${var.issue_client_certificate}"
}
}
node_config {
machine_type = "${var.machine_type}"
oauth_scopes = [ "https://www.googleapis.com/auth/cloud-platform" ]
service_account = "${var.service_account_email}"
}
}
What, if anything, would I have to add to the cluster configuration? Thanks.
You will need to grant the GKE service account access to the GCS bucket that is storing the private images: https://cloud.google.com/container-registry/docs/access-control