Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed Oct 14, 2021
1 parent 0be39d3 commit 34bf362
Show file tree
Hide file tree
Showing 13 changed files with 308 additions and 0 deletions.
7 changes: 7 additions & 0 deletions patch-aws-auth/data.eks.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
eata "aws_eks_cluster" "cluster" {
name = var.cluster_name
}

data "aws_eks_cluster_auth" "cluster" {
name = var.cluster_name
}
1 change: 1 addition & 0 deletions patch-aws-auth/data.tf
1 change: 1 addition & 0 deletions patch-aws-auth/defaults.tf
12 changes: 12 additions & 0 deletions patch-aws-auth/examples/settings.aws-auth.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
locals {
aws_auth_users = []
aws_auth_roles = [
{
# rolearn: data.terraform_remote_state.applications_apps-adsd-eks_vpc_east_vpc2_apps_eks-adsd-cumulus-dev.outputs.role_cluster-admin-role_arn
rolearn : ""
aws_rolename : format("%v%v-cluster-admin", local._prefixes["eks-role"], var.cluster_name)
username : "admin"
groups = ["system:masters", "eks-console-dashboard-full-access-group"]
},
]
}
23 changes: 23 additions & 0 deletions patch-aws-auth/examples/variables.aws-auth.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# maybe just ignore the ARN entirely and force a read

variable "aws_auth_users" {
description = "A list of objects where each object has userarn, aws_username, (k8s) username, and (k8s) groups, where groups is a list of groups to associate with the user. Leaving userarn as an empty string will pull the user ARN from AWS."
type = list(object({
userarn = string
aws_username = string
username = string
groups = list(string)
}))
default = []
}

variable "aws_auth_roles" {
description = "A list of objects where each object has rolearn, aws_rolename, (k8s) username, and (k8s) groups, where groups is a list of groups to associate with the role. Leaving rolearn as an empty string will pull the role ARN from AWS."
type = list(object({
rolearn = string
aws_rolename = string
username = string
groups = list(string)
}))
default = []
}
32 changes: 32 additions & 0 deletions patch-aws-auth/kubeconfig.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# establish kubeconfig file needed for kubectl patch command
# requires kubectl command in the path

resource "null_resource" "kubeconfig" {
# triggers = {
# always_run = timestamp()
# }
provisioner "local-exec" {
command = "which kubectl > /dev/null 2>&1; if [ $? != 0 ]; then 'echo missing kubectl'; exit 1; else exit 0; fi"
}
provisioner "local-exec" {
command = "test -d '${path.root}/setup' || mkdir '${path.root}/setup'"
}
provisioner "local-exec" {
environment = {
AWS_PROFILE = var.profile
AWS_REGION = var.region
}
command = "aws eks update-kubeconfig --name ${var.cluster_name} --kubeconfig ${path.root}/setup/aws-auth.kube.config"
}
depends_on = [data.aws_eks_cluster.cluster]
}

#---
# call it like
#---
## provisioner "local-exec" {
## environment = {
## KUBECONFIG = "${path.root}/setup/kube.config"
## }
## command = "kubectli set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true"
## }
6 changes: 6 additions & 0 deletions patch-aws-auth/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
locals {
region = data.aws_region.current.name
aws_eks_cluster_auth = data.aws_eks_cluster_auth.cluster
aws_eks_cluster = data.aws_eks_cluster.cluster
}

165 changes: 165 additions & 0 deletions patch-aws-auth/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
* # About patch-aws-auth
*
* # Example variable usage
*
* ```hcl
* # settings.auto.tfvars
* aws_auth_users = [
* {
* userarn = ""
* aws_username = "a-ashle001"
* username = "admin"
* groups = ["system:masters", "eks-console-dashboard-full-access-group"]
* },
* ]
* aws_auth_roles = [
* {
* rolearn : ""
* aws_rolename : "r-inf-cloud-admin"
* username : "admin"
* groups = ["eks-console-dashboard-full-access-group"]
* },
* ]
* ```
*
* ```hcl
* # patch-aws-auth.tf
* module "awsauth_base_users" {
* source = THIS
*
* cluster_name = "adsd-cumulus-dev"
* aws_auth_users = var.aws_auth_users
* aws_auth_roles = var.aws_auth_roles
* }
* ```
*/


# pull in current configmap aws-auth
data "kubernetes_config_map" "aws-auth" {
metadata {
name = "aws-auth"
namespace = "kube-system"
}
}

# map users without ARNs to arns
data "aws_iam_user" "auth_users" {
for_each = toset([for u in local.joined_auth_users : u.aws_username])
user_name = each.key
}

# map roles without ARNs to arns
data "aws_iam_role" "auth_roles" {
for_each = toset([for r in local.joined_auth_roles : r.aws_rolename])
name = each.key
}

locals {
existing_roles_string = lookup(data.kubernetes_config_map.aws-auth.data, "mapRoles", "")
existing_users_string = lookup(data.kubernetes_config_map.aws-auth.data, "mapUsers", "")

existing_roles = local.existing_roles_string != "" ? yamldecode(local.existing_roles_string) : []
existing_users = local.existing_users_string != "" ? yamldecode(local.existing_users_string) : []

joined_auth_users = concat(local.aws_auth_users, var.aws_auth_users)
joined_auth_roles = concat(local.aws_auth_roles, var.aws_auth_roles)

mapped_auth_users = [for u in local.joined_auth_users : {
userarn = data.aws_iam_user.auth_users[u.aws_username].arn
aws_username = u.aws_username
username = u.username
groups = u.groups
}]
mapped_auth_roles = [for u in local.joined_auth_roles : {
rolearn = data.aws_iam_role.auth_roles[u.aws_rolename].arn
aws_rolename = u.aws_rolename
username = u.username
groups = u.groups
}]

merged_users = merge(
{ for user in local.existing_users : user.userarn => user },
# { for user in local.aws_auth_users : user.userarn => user },
# { for user in var.aws_auth_users : user.userarn => user }
{ for user in local.mapped_auth_users : user.userarn => user },
)

merged_roles = merge(
{ for role in local.existing_roles : role.rolearn => role },
# { for role in local.aws_auth_roles : role.rolearn => role },
# { for role in var.aws_auth_roles : role.rolearn => role }
{ for role in local.mapped_auth_roles : role.rolearn => role },
)

# patch = yamlencode({
# "data" = {
# "mapUsers" = values(local.merged_users)
# "mapRoles" = values(local.merged_roles)
# }
# })
patch = <<EOM
data:
%{if length(local.merged_roles) > 0~}
mapRoles: |
%{for k, v in local.merged_roles~}
- rolearn: ${v.rolearn}
username: ${v.username}
groups:
%{for g in v.groups~}
- ${g}
%{endfor~}
%{endfor~}
%{endif~}
%{if length(local.merged_users) > 0~}
mapUsers: |
%{for k, v in local.merged_users~}
- userarn: ${v.userarn}
username: ${v.username}
groups:
%{for g in v.groups~}
- ${g}
%{endfor~}
%{endfor~}
%{endif~}
EOM

# patch_t = templatefile("${path.root}/config_map.aws-auth.yaml.tpl",{
# users = values(local.merged_users)
# roles = values(local.merged_roles)
# })
}

resource "null_resource" "patch-aws-auth" {
triggers = {
users = join(",", sort(keys(local.merged_users)))
roles = join(",", sort(keys(local.merged_roles)))
}
depends_on = [null_resource.kubeconfig]

provisioner "local-exec" {
command = "test -d ${path.root}/setup || mkdir ${path.root}/setup"
}
provisioner "local-exec" {
working_dir = "${path.root}/setup"
command = "echo '${local.patch}' > config_map.aws-auth.patch.yaml"
}
provisioner "local-exec" {
working_dir = "${path.root}/setup"
command = "kubectl --kubeconfig aws-auth.kube.config patch --type merge -n kube-system configmap/aws-auth --patch-file config_map.aws-auth.patch.yaml"
}
}

# output "map" {
# value = data.kubernetes_config_map.aws-auth
# }
# output "map_output" {
# value = {
# "object" = data.kubernetes_config_map.aws-auth
# "existing_users" = local.existing_users
# "existing_roles" = local.existing_roles
# "patch" = local.patch
# "patch_text" = local.patch_t
# }
# }
1 change: 1 addition & 0 deletions patch-aws-auth/prefixes.tf
19 changes: 19 additions & 0 deletions patch-aws-auth/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
terraform {
required_version = ">= 0.12.31"
}

provider "kubernetes" {
host = local.aws_eks_cluster.endpoint

cluster_ca_certificate = base64decode(local.aws_eks_cluster.certificate_authority[0].data)
token = local.aws_eks_cluster_auth.token
}

# provider "helm" {
# kubernetes {
# host = local.aws_eks_cluster.endpoint
#
# cluster_ca_certificate = base64decode(local.aws_eks_cluster.certificate_authority[0].data)
# token = local.aws_eks_cluster_auth.token
# }
# }
17 changes: 17 additions & 0 deletions patch-aws-auth/templates/config_map.aws-auth.yaml.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
data:
%{ if length(roles) > 0 }
mapRoles: |
%{ for k, v in roles ~}
- rolearn: ${v.rolearn}
username: ${v.username}
groups: ${v.groups}
%{ endfor ~}
%{ endif }
%{ if length(users) > 0 }
mapUsers: |
%{ for k, v in users ~}
- userarn: ${v.userarn}
username: ${v.username}
groups: ${v.groups}
%{ endfor ~}
%{ endif }
23 changes: 23 additions & 0 deletions patch-aws-auth/variables.aws-auth.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# maybe just ignore the ARN entirely and force a read

variable "aws_auth_users" {
description = "A list of objects where each object has userarn, aws_username, (k8s) username, and (k8s) groups, where groups is a list of groups to associate with the user. Leaving userarn as an empty string will pull the user ARN from AWS."
type = list(object({
userarn = string
aws_username = string
username = string
groups = list(string)
}))
default = []
}

variable "aws_auth_roles" {
description = "A list of objects where each object has rolearn, aws_rolename, (k8s) username, and (k8s) groups, where groups is a list of groups to associate with the role. Leaving rolearn as an empty string will pull the role ARN from AWS."
type = list(object({
rolearn = string
aws_rolename = string
username = string
groups = list(string)
}))
default = []
}
1 change: 1 addition & 0 deletions patch-aws-auth/variables.eks.tf

0 comments on commit 34bf362

Please sign in to comment.