Skip to content

Commit

Permalink
infra/gcp: manage aaa secrets via terraform
Browse files Browse the repository at this point in the history
  • Loading branch information
spiffxp committed Nov 3, 2021
1 parent 3b2e07f commit 305408e
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 78 deletions.
78 changes: 0 additions & 78 deletions infra/gcp/bash/ensure-main-project.sh
Original file line number Diff line number Diff line change
Expand Up @@ -348,81 +348,6 @@ EOF
read -rs
}

# Eventually we would like to use kubernetes-external-secrets to manage
# all secrets in aaa; not sure how far we are on that. So for now, at least
# ensure that the existing kubernetes-public secrets created for humans
# to manually sync into the aaa cluster are managed by this script.
function ensure_aaa_external_secrets() {
if [ $# -ne 1 ] || [ -z "$1" ]; then
echo "${FUNCNAME[0]}(project) requires 1 argument" >&2
return 1
fi
local project="${1}"
local secret_specs=()

# another sign that we should move to using YAML as source of intent;
# bash and indirect array access don't play nice, so we get this...

# prow as in the k8s-infra-prow instance being stood up on aaa, not the
# build clusters managed via infra/gcp/terraform/k8s-infra-prow-build*
local prow_secrets=(
k8s-infra-build-clusters-kubeconfig
k8s-infra-cherrypick-robot-github-token
k8s-infra-ci-robot-github-account-password
k8s-infra-ci-robot-github-token
k8s-infra-prow-cookie
k8s-infra-prow-github-oauth-config
k8s-infra-prow-hmac-token
)
local publishing_bot_secrets=(
publishing-bot-github-token
)
local slack_infra_secrets=(
recaptcha-secret-key
recaptcha-site-key
slack-event-log-config
slack-moderator-config
slack-moderator-words-config
slack-post-message-config
slack-welcomer-config
slackin-token
)
local triageparty_release_secrets=(
triage-party-github-token
)
local elekto_secrets=(
elekto-db-database
elekto-db-host
elekto-db-password
elekto-db-port
elekto-db-username
elekto-github-client-id
elekto-github-client-secret
elekto-meta-secret
)
mapfile -t secret_specs < <(
printf "%s/prow/sig-testing\n" "${prow_secrets[@]}"
printf "%s/publishing-bot/sig-release\n" "${publishing_bot_secrets[@]}"
printf "%s/slack-infra/sig-contributor-experience\n" "${slack_infra_secrets[@]}"
printf "%s/triageparty-release/sig-release\n" "${triageparty_release_secrets[@]}"
printf "%s/elekto/sig-contributor-experience\n" "${elekto_secrets[@]}"
)

for spec in "${secret_specs[@]}"; do
local secret app k8s_group
secret="$(echo "${spec}" | cut -d/ -f1)"
app="$(echo "${spec}" | cut -d/ -f2)"
k8s_group="$(echo "${spec}" | cut -d/ -f3)"

local admins="k8s-infra-rbac-${app}@kubernetes.io"
local labels=("app=${app}" "group=${k8s_group}")

color 6 "Ensuring '${app}' secret '${secret}' exists in '${project}' and is owned by '${admins}'"
ensure_secret_with_admins "${project}" "${secret}" "${admins}"
ensure_secret_labels "${project}" "${secret}" "${labels[@]}"
done
}

# Special-case IAM bindings that are necessary for k8s-infra prow or
# its build clusters to operate on resources within the given project
function ensure_prow_special_cases {
Expand Down Expand Up @@ -505,9 +430,6 @@ function ensure_main_project() {
color 6 "Ensuring DNS is configured in: ${project}"
ensure_dns "${project}" 2>&1 | indent

color 6 "Ensuring secrets destined for apps in 'aaa' exist in: ${project}"
ensure_aaa_external_secrets "${project}" 2>&1 | indent

color 6 "Ensuring prow special cases for: ${project}"
ensure_prow_special_cases "${project}" 2>&1 | indent

Expand Down
109 changes: 109 additions & 0 deletions infra/gcp/terraform/kubernetes-public/secrets.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

locals {
aaa_apps = {
elekto = {
group = "sig-contributor-experience"
secrets = [
"elekto-db-database",
"elekto-db-host",
"elekto-db-password",
"elekto-db-port",
"elekto-db-username",
"elekto-github-client-id",
"elekto-github-client-secret",
"elekto-meta-secret",
]
},
prow = {
group = "sig-testing"
secrets = [
"k8s-infra-build-clusters-kubeconfig",
"k8s-infra-cherrypick-robot-github-token",
"k8s-infra-ci-robot-github-account-password",
"k8s-infra-ci-robot-github-token",
"k8s-infra-prow-cookie",
"k8s-infra-prow-github-oauth-config",
"k8s-infra-prow-hmac-token",
]
},
publishing-bot = {
group = "sig-release"
secrets = [
"publishing-bot-github-token",
]
},
slack-infra = {
group = "sig-contributor-experience"
secrets = [
"recaptcha-secret-key",
"recaptcha-site-key",
"slack-event-log-config",
"slack-moderator-config",
"slack-moderator-words-config",
"slack-post-message-config",
"slack-welcomer-config",
"slackin-token",
]
},
triageparty-release = {
group = "sig-release"
secrets = [
"triage-party-github-token",
]
},
}
// Even though we could just use the list, we're going to keep parity with
// the map structure used in k8s-infra-prow-build, so resource definitions
// look similar
aaa_app_secrets = {
for s in flatten([
for app_name, app in local.aaa_apps : [
for secret in app.secrets : {
app = app_name
group = app.group
owners = "k8s-infra-rbac-${app_name}@kubernetes.io"
secret = secret
}
]
]) : s.secret => s
}
}

resource "google_secret_manager_secret" "aaa_app_secrets" {
for_each = local.aaa_app_secrets
project = data.google_project.project.project_id
secret_id = each.key
labels = {
app = each.value.app
group = each.value.group
}
replication {
automatic = true
}
}


resource "google_secret_manager_secret_iam_binding" "aaa_app_secret_admins" {
for_each = local.aaa_app_secrets
project = google_secret_manager_secret.aaa_app_secrets[each.key].project
secret_id = google_secret_manager_secret.aaa_app_secrets[each.key].id
role = "roles/secretmanager.admin"
members = [
"group:${each.value.owners}"
]
}

0 comments on commit 305408e

Please sign in to comment.