Skip to content

Commit

Permalink
Feature: Namespace and Name List (#31)
Browse files Browse the repository at this point in the history
* supports a list of any or all value list

* Auto Format

* Update variables.tf

Co-authored-by: Andriy Knysh <[email protected]>

* Auto Format

* update test and variable description for lint

* cleanup and docs

* Auto Format

Co-authored-by: cloudpossebot <[email protected]>
Co-authored-by: Andriy Knysh <[email protected]>
  • Loading branch information
3 people authored Dec 27, 2022
1 parent b873737 commit 981bc51
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 9 deletions.
1 change: 1 addition & 0 deletions .github/workflows/validate-codeowners.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
steps:
- name: "Checkout source code at current commit"
uses: actions/checkout@v2
# Leave pinned at 0.7.1 until https://github.com/mszostok/codeowners-validator/issues/173 is resolved
- uses: mszostok/[email protected]
if: github.event.pull_request.head.repo.full_name == github.repository
name: "Full check of CODEOWNERS"
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,10 @@ Available targets:
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
| <a name="input_permissions_boundary"></a> [permissions\_boundary](#input\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the role. | `string` | `null` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_service_account_name"></a> [service\_account\_name](#input\_service\_account\_name) | Kubernetes ServiceAccount name | `string` | n/a | yes |
| <a name="input_service_account_namespace"></a> [service\_account\_namespace](#input\_service\_account\_namespace) | Kubernetes Namespace where service account is deployed | `string` | n/a | yes |
| <a name="input_service_account_list_qualifier"></a> [service\_account\_list\_qualifier](#input\_service\_account\_list\_qualifier) | Kubernetes ServiceAccount list qualifier, must be one of `ForAllValues` or `ForAnyValue` | `string` | `"ForAnyValue"` | no |
| <a name="input_service_account_name"></a> [service\_account\_name](#input\_service\_account\_name) | Kubernetes ServiceAccount name | `string` | `null` | no |
| <a name="input_service_account_namespace"></a> [service\_account\_namespace](#input\_service\_account\_namespace) | Kubernetes Namespace where service account is deployed | `string` | `null` | no |
| <a name="input_service_account_namespace_name_list"></a> [service\_account\_namespace\_name\_list](#input\_service\_account\_namespace\_name\_list) | List of `namespace:name` for service account assume role IAM policy | `list(string)` | `null` | no |
| <a name="input_stage"></a> [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).<br>Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no |
| <a name="input_tenant"></a> [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no |
Expand Down Expand Up @@ -410,7 +412,7 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply

[![README Footer][readme_footer_img]][readme_footer_link]
[![Beacon][beacon]][website]

<!-- markdownlint-disable -->
[logo]: https://cloudposse.com/logo-300x69.svg
[docs]: https://cpco.io/docs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-eks-iam-role&utm_content=docs
[website]: https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-eks-iam-role&utm_content=website
Expand Down Expand Up @@ -441,3 +443,4 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply
[share_googleplus]: https://plus.google.com/share?url=https://github.com/cloudposse/terraform-aws-eks-iam-role
[share_email]: mailto:?subject=terraform-aws-eks-iam-role&body=https://github.com/cloudposse/terraform-aws-eks-iam-role
[beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/terraform-aws-eks-iam-role?pixel&cs=github&cm=readme&an=terraform-aws-eks-iam-role
<!-- markdownlint-restore -->
6 changes: 4 additions & 2 deletions docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
| <a name="input_permissions_boundary"></a> [permissions\_boundary](#input\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the role. | `string` | `null` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_service_account_name"></a> [service\_account\_name](#input\_service\_account\_name) | Kubernetes ServiceAccount name | `string` | n/a | yes |
| <a name="input_service_account_namespace"></a> [service\_account\_namespace](#input\_service\_account\_namespace) | Kubernetes Namespace where service account is deployed | `string` | n/a | yes |
| <a name="input_service_account_list_qualifier"></a> [service\_account\_list\_qualifier](#input\_service\_account\_list\_qualifier) | Kubernetes ServiceAccount list qualifier, must be one of `ForAllValues` or `ForAnyValue` | `string` | `"ForAnyValue"` | no |
| <a name="input_service_account_name"></a> [service\_account\_name](#input\_service\_account\_name) | Kubernetes ServiceAccount name | `string` | `null` | no |
| <a name="input_service_account_namespace"></a> [service\_account\_namespace](#input\_service\_account\_namespace) | Kubernetes Namespace where service account is deployed | `string` | `null` | no |
| <a name="input_service_account_namespace_name_list"></a> [service\_account\_namespace\_name\_list](#input\_service\_account\_namespace\_name\_list) | List of `namespace:name` for service account assume role IAM policy | `list(string)` | `null` | no |
| <a name="input_stage"></a> [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).<br>Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no |
| <a name="input_tenant"></a> [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no |
Expand Down
24 changes: 24 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ data "aws_caller_identity" "current" {}
module "autoscaler_role" {
source = "../.."

# Singular Service Account attachment
service_account_name = "autoscaler"
service_account_namespace = "kube-system"

Expand All @@ -19,6 +20,29 @@ module "autoscaler_role" {
context = module.this.context
}

module "autoscaler_role_multiple_service_accounts" {
source = "../.."
attributes = ["multiple", "sa"]

# Usually there is no need to add both service account methods of attachment.
# If you add both, they are joined via AND.
# See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_multi-value-conditions.html#reference_policies_multiple-conditions-eval

# Multiple Service Account attachments
service_account_namespace_name_list = [
"kube-system:autoscaler",
"default:foo",
]
service_account_list_qualifier = "ForAnyValue"

aws_account_number = data.aws_caller_identity.current.account_id
# Rather than create a whole cluster, just fake the OIDC URL
# eks_cluster_oidc_issuer_url = module.eks_cluster.eks_cluster_identity_oidc_issuer
eks_cluster_oidc_issuer_url = "https://oidc.eks.us-west-2.amazonaws.com/id/FEDCBA9876543210FEDCBA9876543210"
aws_iam_policy_document = [data.aws_iam_policy_document.autoscaler.json]

context = module.this.context
}
data "aws_iam_policy_document" "autoscaler" {
statement {
sid = "AllowToScaleEKSNodeGroupAutoScalingGroup"
Expand Down
22 changes: 18 additions & 4 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,24 @@ data "aws_iam_policy_document" "service_account_assume_role" {
identifiers = [format("arn:%s:iam::%s:oidc-provider/%s", var.aws_partition, local.aws_account_number, local.eks_cluster_oidc_issuer)]
}

condition {
test = "StringLike"
values = [format("system:serviceaccount:%s:%s", coalesce(var.service_account_namespace, "*"), coalesce(var.service_account_name, "*"))]
variable = format("%s:sub", local.eks_cluster_oidc_issuer)
dynamic "condition" {
for_each = var.service_account_name != null && var.service_account_namespace != null ? ["true"] : []
content {
test = "StringLike"
values = [
format("system:serviceaccount:%s:%s", coalesce(var.service_account_namespace, "*"), coalesce(var.service_account_name, "*"))
]
variable = format("%s:sub", local.eks_cluster_oidc_issuer)
}
}

dynamic "condition" {
for_each = var.service_account_namespace_name_list != null ? ["true"] : []
content {
test = format("%s:StringLike", var.service_account_list_qualifier)
values = formatlist("system:serviceaccount:%s", var.service_account_namespace_name_list)
variable = format("%s:sub", local.eks_cluster_oidc_issuer)
}
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
variable "service_account_name" {
type = string
description = "Kubernetes ServiceAccount name"
default = null
}

variable "service_account_namespace" {
type = string
description = "Kubernetes Namespace where service account is deployed"
default = null
}

variable "service_account_list_qualifier" {
type = string
description = "Kubernetes ServiceAccount list qualifier, must be one of `ForAllValues` or `ForAnyValue`"
validation {
condition = contains(["ForAllValues", "ForAnyValue"], var.service_account_list_qualifier)
error_message = "Kubernetes ServiceAccount list qualifier must be one of `ForAllValues` or `ForAnyValue`."
}
default = "ForAnyValue"
}

variable "service_account_namespace_name_list" {
type = list(string)
description = "List of `namespace:name` for service account assume role IAM policy"
default = null
}

variable "aws_account_number" {
Expand Down

0 comments on commit 981bc51

Please sign in to comment.