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: Add support for inline policy for IAM EKS Role #502

Closed
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
1 change: 1 addition & 0 deletions examples/iam-eks-role/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Run `terraform destroy` when you don't need these resources.
| Name | Source | Version |
|------|--------|---------|
| <a name="module_eks"></a> [eks](#module\_eks) | terraform-aws-modules/eks/aws | ~> 18.0 |
| <a name="module_iam_assumable_role_inline_policy"></a> [iam\_assumable\_role\_inline\_policy](#module\_iam\_assumable\_role\_inline\_policy) | ../../modules/iam-eks-role | n/a |
| <a name="module_iam_eks_role"></a> [iam\_eks\_role](#module\_iam\_eks\_role) | ../../modules/iam-eks-role | n/a |
| <a name="module_iam_eks_role_with_assume_wildcard"></a> [iam\_eks\_role\_with\_assume\_wildcard](#module\_iam\_eks\_role\_with\_assume\_wildcard) | ../../modules/iam-eks-role | n/a |
| <a name="module_iam_eks_role_with_self_assume"></a> [iam\_eks\_role\_with\_self\_assume](#module\_iam\_eks\_role\_with\_self\_assume) | ../../modules/iam-eks-role | n/a |
Expand Down
41 changes: 41 additions & 0 deletions examples/iam-eks-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,44 @@ data "aws_subnets" "all" {
values = [data.aws_vpc.default.id]
}
}

#####################################
# IAM assumable role with inline policy
#####################################
module "iam_assumable_role_inline_policy" {
source = "../../modules/iam-eks-role"

create_role = true

role_name = "my-app-inline-policy"

cluster_service_accounts = {
(random_pet.this.id) = ["default:my-app"]
}

tags = {
Name = "eks-role"
}

inline_policy_statements = [
{
sid = "AllowECRPushPull"
actions = [
"ecr:GetAuthorizationToken",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchCheckLayerAvailability",
"ecr:DescribeImages",
"ecr:DescribeRepositories",
"ecr:GetDownloadUrlForLayer",
"ecr:ListImages",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
]
effect = "Allow"
resources = ["*"]
}
]
}
3 changes: 3 additions & 0 deletions modules/iam-eks-role/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@ No modules.
| Name | Type |
|------|------|
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.inline](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_eks_cluster.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source |
| [aws_iam_policy_document.assume_role_with_oidc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.inline](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |

## Inputs
Expand All @@ -112,6 +114,7 @@ No modules.
| <a name="input_cluster_service_accounts"></a> [cluster\_service\_accounts](#input\_cluster\_service\_accounts) | EKS cluster and k8s ServiceAccount pairs. Each EKS cluster can have multiple k8s ServiceAccount. See README for details | `map(list(string))` | `{}` | no |
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `true` | no |
| <a name="input_force_detach_policies"></a> [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no |
| <a name="input_inline_policy_statements"></a> [inline\_policy\_statements](#input\_inline\_policy\_statements) | List of inline policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) to attach to IAM role as an inline policy | `any` | `[]` | no |
| <a name="input_max_session_duration"></a> [max\_session\_duration](#input\_max\_session\_duration) | Maximum CLI/API session duration in seconds between 3600 and 43200 | `number` | `43200` | no |
| <a name="input_role_description"></a> [role\_description](#input\_role\_description) | IAM Role description | `string` | `""` | no |
| <a name="input_role_name"></a> [role\_name](#input\_role\_name) | Name of IAM role | `string` | `null` | no |
Expand Down
61 changes: 61 additions & 0 deletions modules/iam-eks-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,64 @@ resource "aws_iam_role_policy_attachment" "this" {
role = aws_iam_role.this[0].name
policy_arn = each.value
}

###############################
# IAM Role Inline policy
###############################

locals {
create_iam_role_inline_policy = var.create_role && length(var.inline_policy_statements) > 0
}

data "aws_iam_policy_document" "inline" {
count = local.create_iam_role_inline_policy ? 1 : 0

dynamic "statement" {
for_each = var.inline_policy_statements

content {
sid = try(statement.value.sid, null)
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
not_resources = try(statement.value.not_resources, null)

dynamic "principals" {
for_each = try(statement.value.principals, [])

content {
type = principals.value.type
identifiers = principals.value.identifiers
}
}

dynamic "not_principals" {
for_each = try(statement.value.not_principals, [])

content {
type = not_principals.value.type
identifiers = not_principals.value.identifiers
}
}

dynamic "condition" {
for_each = try(statement.value.conditions, [])

content {
test = condition.value.test
values = condition.value.values
variable = condition.value.variable
}
}
}
}
}

resource "aws_iam_role_policy" "inline" {
count = local.create_iam_role_inline_policy ? 1 : 0

role = aws_iam_role.this[0].name
name_prefix = "${var.role_name}_inline_"
policy = data.aws_iam_policy_document.inline[0].json
}
6 changes: 6 additions & 0 deletions modules/iam-eks-role/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ variable "role_policy_arns" {
default = {}
}

variable "inline_policy_statements" {
description = "List of inline policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) to attach to IAM role as an inline policy"
type = any
default = []
}

variable "cluster_service_accounts" {
description = "EKS cluster and k8s ServiceAccount pairs. Each EKS cluster can have multiple k8s ServiceAccount. See README for details"
type = map(list(string))
Expand Down
1 change: 1 addition & 0 deletions wrappers/iam-eks-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module "wrapper" {
cluster_service_accounts = try(each.value.cluster_service_accounts, var.defaults.cluster_service_accounts, {})
create_role = try(each.value.create_role, var.defaults.create_role, true)
force_detach_policies = try(each.value.force_detach_policies, var.defaults.force_detach_policies, false)
inline_policy_statements = try(each.value.inline_policy_statements, var.defaults.inline_policy_statements, [])
max_session_duration = try(each.value.max_session_duration, var.defaults.max_session_duration, 43200)
role_description = try(each.value.role_description, var.defaults.role_description, "")
role_name = try(each.value.role_name, var.defaults.role_name, null)
Expand Down