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 custom trust policy conditions on iam-github-oidc-role #547

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
12 changes: 12 additions & 0 deletions examples/iam-github-oidc/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ module "iam_github_oidc_role" {
"terraform-aws-modules/terraform-aws-iam:ref:refs/heads/master",
]

# This ensures that the OIDC token GitHub uses to assume the AWS IAM role has the correct
# `actor` scope. Any other GitHub OIDC claims can be used as well.
additional_provider_trust_policy_conditions = [
{
test = "StringEquals"
variable = "${module.iam_github_oidc_provider.url}:actor"
# This should be the list of GitHub usernames for which you want to restrict
# access to the role.
values = ["username"]
}
]

policies = {
additional = aws_iam_policy.additional.arn
S3ReadOnly = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
Expand Down
1 change: 1 addition & 0 deletions modules/iam-github-oidc-role/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_provider_trust_policy_conditions"></a> [additional\_provider\_trust\_policy\_conditions](#input\_additional\_provider\_trust\_policy\_conditions) | [Condition constraints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#condition) applied to the trust policy | <pre>list(object({<br/> test = string<br/> variable = string<br/> values = list(string)<br/> }))</pre> | `[]` | no |
| <a name="input_audience"></a> [audience](#input\_audience) | Audience to use for OIDC role. Defaults to `sts.amazonaws.com` for use with the [official AWS GitHub action](https://github.com/aws-actions/configure-aws-credentials) | `string` | `"sts.amazonaws.com"` | no |
| <a name="input_create"></a> [create](#input\_create) | Controls if resources should be created (affects all resources) | `bool` | `true` | no |
| <a name="input_description"></a> [description](#input\_description) | IAM Role description | `string` | `null` | no |
Expand Down
10 changes: 10 additions & 0 deletions modules/iam-github-oidc-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ data "aws_iam_policy_document" "this" {
# Strip `repo:` to normalize for cases where users may prepend it
values = [for subject in var.subjects : "repo:${trimprefix(subject, "repo:")}"]
}

dynamic "condition" {
for_each = var.additional_provider_trust_policy_conditions

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

Expand Down
10 changes: 10 additions & 0 deletions modules/iam-github-oidc-role/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,13 @@ variable "provider_url" {
type = string
default = "token.actions.githubusercontent.com"
}

variable "additional_provider_trust_policy_conditions" {
description = "[Condition constraints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#condition) applied to the trust policy"
type = list(object({
test = string
variable = string
values = list(string)
}))
default = []
}
29 changes: 15 additions & 14 deletions wrappers/iam-github-oidc-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ module "wrapper" {

for_each = var.items

audience = try(each.value.audience, var.defaults.audience, "sts.amazonaws.com")
create = try(each.value.create, var.defaults.create, true)
description = try(each.value.description, var.defaults.description, null)
force_detach_policies = try(each.value.force_detach_policies, var.defaults.force_detach_policies, true)
max_session_duration = try(each.value.max_session_duration, var.defaults.max_session_duration, null)
name = try(each.value.name, var.defaults.name, null)
name_prefix = try(each.value.name_prefix, var.defaults.name_prefix, null)
path = try(each.value.path, var.defaults.path, "/")
permissions_boundary_arn = try(each.value.permissions_boundary_arn, var.defaults.permissions_boundary_arn, null)
policies = try(each.value.policies, var.defaults.policies, {})
provider_url = try(each.value.provider_url, var.defaults.provider_url, "token.actions.githubusercontent.com")
subject_condition = try(each.value.subject_condition, var.defaults.subject_condition, "StringLike")
subjects = try(each.value.subjects, var.defaults.subjects, [])
tags = try(each.value.tags, var.defaults.tags, {})
additional_provider_trust_policy_conditions = try(each.value.additional_provider_trust_policy_conditions, var.defaults.additional_provider_trust_policy_conditions, [])
audience = try(each.value.audience, var.defaults.audience, "sts.amazonaws.com")
create = try(each.value.create, var.defaults.create, true)
description = try(each.value.description, var.defaults.description, null)
force_detach_policies = try(each.value.force_detach_policies, var.defaults.force_detach_policies, true)
max_session_duration = try(each.value.max_session_duration, var.defaults.max_session_duration, null)
name = try(each.value.name, var.defaults.name, null)
name_prefix = try(each.value.name_prefix, var.defaults.name_prefix, null)
path = try(each.value.path, var.defaults.path, "/")
permissions_boundary_arn = try(each.value.permissions_boundary_arn, var.defaults.permissions_boundary_arn, null)
policies = try(each.value.policies, var.defaults.policies, {})
provider_url = try(each.value.provider_url, var.defaults.provider_url, "token.actions.githubusercontent.com")
subject_condition = try(each.value.subject_condition, var.defaults.subject_condition, "StringLike")
subjects = try(each.value.subjects, var.defaults.subjects, [])
tags = try(each.value.tags, var.defaults.tags, {})
}