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

feat(doks,doks-public) create infraciadmin SA for each cluster along with their token and kubeconfigs #134

Merged
merged 2 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion .shared-tools
Submodule .shared-tools updated 1 files
+1 −1 Jenkinsfile_k8s
38 changes: 38 additions & 0 deletions .terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Jenkinsfile_k8s
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ parallel(
terraform(
// "Read only" token
stagingCredentials: [
string(variable: 'TF_VAR_do_token', credentialsId:'staging-terraform-digitalocean-pat'),
string(variable: 'DIGITALOCEAN_ACCESS_TOKEN', credentialsId:'staging-terraform-digitalocean-pat'),
file(variable: 'BACKEND_CONFIG_FILE', credentialsId: 'staging-terraform-digitalocean-backend-config'),
],
// "Read write" token
productionCredentials: [
string(variable: 'TF_VAR_do_token', credentialsId:'production-terraform-digitalocean-pat'),
string(variable: 'DIGITALOCEAN_ACCESS_TOKEN', credentialsId:'production-terraform-digitalocean-pat'),
file(variable: 'BACKEND_CONFIG_FILE', credentialsId: 'production-terraform-digitalocean-backend-config'),
],
)
Expand Down
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This repository hosts the infrastructure-as-code definition for all the link:htt

== Requirements

* A Digital Ocean account with a personal access token defined as the value of the environment variable `TF_VAR_do_token`
* A Digital Ocean account with a personal access token defined as the value of the environment variable `DIGITALOCEAN_ACCESS_TOKEN`
* The requirements (of the shared tools) listed at link:{shared_tools_repo_url}/tree/main/terraform#requirements[{shared_tools_repo_name}/terraform#requirements]
* The link:https://www.terraform.io/docs/language/settings/backends/s3.html[Terraform S3 Backend Configuration] on a local file named `backend-config`:
** The content can be retrieved from the outputs of the link:{private_repo_url}[(private) repository {private_repo_name}]
Expand Down
80 changes: 80 additions & 0 deletions doks-cluster.tf
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,83 @@ resource "digitalocean_kubernetes_node_pool" "autoscaled-pool" {
]
}
}

# Data source required as per https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/kubernetes_cluster#kubernetes-terraform-provider-example
# To configure the kuberenetes provider
dduportal marked this conversation as resolved.
Show resolved Hide resolved
data "digitalocean_kubernetes_cluster" "doks" {
name = local.cluster_name
depends_on = [digitalocean_kubernetes_cluster.doks_cluster]
}
provider "kubernetes" {
alias = "doks"
host = data.digitalocean_kubernetes_cluster.doks.kube_config.0.host
cluster_ca_certificate = base64decode(data.digitalocean_kubernetes_cluster.doks.kube_config.0.cluster_ca_certificate)
# Bootstrap requires to use the Digital Ocean API user as no service account or technical user are created in the cluster
dduportal marked this conversation as resolved.
Show resolved Hide resolved
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "doctl"
args = ["kubernetes", "cluster", "kubeconfig", "exec-credential",
"--version=v1beta1", data.digitalocean_kubernetes_cluster.doks.id]
}
}

# Configure the jenkins-infra/kubernetes-management admin service account
resource "kubernetes_service_account_v1" "doks_infraciadmin" {
provider = kubernetes.doks
metadata {
name = local.svcaccount_admin_name
namespace = local.svcaccount_admin_namespace
}
automount_service_account_token = "false"
}
resource "kubernetes_secret_v1" "doks_infraciadmin_token" {
provider = kubernetes.doks
metadata {
name = "${local.svcaccount_admin_name}-token"
namespace = local.svcaccount_admin_namespace
annotations = {
"kubernetes.io/service-account.name" = "${local.svcaccount_admin_name}"
}
}
type = "kubernetes.io/service-account-token"
}
resource "kubernetes_cluster_role_binding" "doks_infraciadmin_clusteradmin" {
provider = kubernetes.doks
metadata {
name = "${local.svcaccount_admin_name}_clusteradmin"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "cluster-admin"
}
subject {
kind = "ServiceAccount"
name = local.svcaccount_admin_name
namespace = local.svcaccount_admin_namespace
}
}

output "kubeconfig_doks" {
sensitive = true
value = <<-EOF
apiVersion: v1
kind: Config
clusters:
- name: ${local.cluster_name}
cluster:
certificate-authority-data: ${data.digitalocean_kubernetes_cluster.doks.kube_config.0.cluster_ca_certificate}
server: ${data.digitalocean_kubernetes_cluster.doks.kube_config.0.host}
contexts:
- name: ${local.svcaccount_admin_name}@${local.cluster_name}
context:
cluster: ${local.cluster_name}
namespace: ${local.svcaccount_admin_namespace}
user: ${local.svcaccount_admin_name}
users:
- name: ${local.svcaccount_admin_name}
user:
token: ${lookup(kubernetes_secret_v1.doks_infraciadmin_token.data, "token")}
current-context: ${local.svcaccount_admin_name}@${local.cluster_name}
EOF
}
80 changes: 80 additions & 0 deletions doks-public-cluster.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,83 @@ resource "digitalocean_kubernetes_cluster" "doks_public_cluster" {
tags = ["public-node-pool", local.public_cluster_name]
}
}

# Data source required as per https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/kubernetes_cluster#kubernetes-terraform-provider-example
# To configure the kuberenetes provider
data "digitalocean_kubernetes_cluster" "doks_public" {
name = local.public_cluster_name
depends_on = [digitalocean_kubernetes_cluster.doks_public_cluster]
}
provider "kubernetes" {
alias = "doks_public"
host = data.digitalocean_kubernetes_cluster.doks_public.kube_config.0.host
cluster_ca_certificate = base64decode(data.digitalocean_kubernetes_cluster.doks_public.kube_config.0.cluster_ca_certificate)
# Bootstrap requires to use the Digital Ocean API user as no service account or technical user are created in the cluster
dduportal marked this conversation as resolved.
Show resolved Hide resolved
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "doctl"
args = ["kubernetes", "cluster", "kubeconfig", "exec-credential",
"--version=v1beta1", data.digitalocean_kubernetes_cluster.doks_public.id]
}
}

# Configure the jenkins-infra/kubernetes-management admin service account
resource "kubernetes_service_account_v1" "doks_public_infraciadmin" {
provider = kubernetes.doks_public
metadata {
name = local.svcaccount_admin_name
namespace = local.svcaccount_admin_namespace
}
automount_service_account_token = "false"
}
resource "kubernetes_secret_v1" "doks_public_infraciadmin_token" {
provider = kubernetes.doks_public
metadata {
name = "${local.svcaccount_admin_name}-token"
namespace = local.svcaccount_admin_namespace
annotations = {
"kubernetes.io/service-account.name" = "${local.svcaccount_admin_name}"
}
}
type = "kubernetes.io/service-account-token"
}
resource "kubernetes_cluster_role_binding" "doks_public_infraciadmin_clusteradmin" {
provider = kubernetes.doks_public
metadata {
name = "${local.svcaccount_admin_name}_clusteradmin"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "cluster-admin"
}
subject {
kind = "ServiceAccount"
name = local.svcaccount_admin_name
namespace = local.svcaccount_admin_namespace
}
}

output "kubeconfig_doks_public" {
sensitive = true
value = <<-EOF
apiVersion: v1
kind: Config
clusters:
- name: ${local.public_cluster_name}
cluster:
certificate-authority-data: ${data.digitalocean_kubernetes_cluster.doks_public.kube_config.0.cluster_ca_certificate}
server: ${data.digitalocean_kubernetes_cluster.doks_public.kube_config.0.host}
contexts:
- name: ${local.svcaccount_admin_name}@${local.public_cluster_name}
context:
cluster: ${local.public_cluster_name}
namespace: ${local.svcaccount_admin_namespace}
user: ${local.svcaccount_admin_name}
users:
- name: ${local.svcaccount_admin_name}
user:
token: ${lookup(kubernetes_secret_v1.doks_public_infraciadmin_token.data, "token")}
current-context: ${local.svcaccount_admin_name}@${local.public_cluster_name}
EOF
}
6 changes: 4 additions & 2 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ resource "random_string" "suffix" {
}

locals {
cluster_name = lower("jenkins-infra-doks-${random_string.suffix.result}")
public_cluster_name = lower("jenkins-infra-doks-public-${random_string.suffix.result}")
cluster_name = lower("jenkins-infra-doks-${random_string.suffix.result}")
public_cluster_name = lower("jenkins-infra-doks-public-${random_string.suffix.result}")
svcaccount_admin_name = "infraciadmin"
svcaccount_admin_namespace = "kube-system"
}
3 changes: 0 additions & 3 deletions providers.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
provider "digitalocean" {
token = var.do_token
}

variable "do_token" {}

provider "local" {
}