Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

infra/gcp: manage aaa secrets via terraform #3028

Merged
merged 1 commit into from
Nov 3, 2021
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
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

honestly also makes for a fairly nice DSL

// 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}"
]
}