Skip to content

Commit ac082ef

Browse files
committed
ROSAENG-6808 | feat: add OCM role submodule with required ROSA CLI tags
Add modules/ocm-role/ that creates the AWS IAM OCM role with the tags the ROSA CLI applies (red-hat-managed, rosa_role_prefix, rosa_role_type, rosa_environment, and conditional rosa_admin_role). Permission policies are read from the rhcs_hcp_policies data source using the policy IDs confirmed in terraform-provider-rhcs PR #1156. The submodule outputs role_arn for composition with the provider's rhcs_rosa_ocm_role_link resource. An example and tests are included. Signed-off-by: lufreita <lufreita@redhat.com>
1 parent 0860fe7 commit ac082ef

11 files changed

Lines changed: 730 additions & 0 deletions

File tree

examples/ocm-role/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# ocm-role example
2+
3+
Creates and links an OCM IAM role with the required ROSA CLI-parity tags using the `ocm-role` module.
4+
5+
<!-- BEGIN_AUTOMATED_TF_DOCS_BLOCK -->
6+
## Requirements
7+
8+
| Name | Version |
9+
| ---- | ------- |
10+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
11+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
12+
| <a name="requirement_rhcs"></a> [rhcs](#requirement\_rhcs) | >= 1.7.7 |
13+
14+
## Providers
15+
16+
No providers.
17+
18+
## Modules
19+
20+
| Name | Source | Version |
21+
| ---- | ------ | ------- |
22+
| <a name="module_ocm_role"></a> [ocm\_role](#module\_ocm\_role) | ../../modules/ocm-role | n/a |
23+
24+
## Resources
25+
26+
No resources.
27+
28+
## Inputs
29+
30+
| Name | Description | Type | Default | Required |
31+
| ---- | ----------- | ---- | ------- | :------: |
32+
| <a name="input_ocm_role_prefix"></a> [ocm\_role\_prefix](#input\_ocm\_role\_prefix) | User-defined prefix for the OCM IAM role name. | `string` | `"ManagedOpenShift"` | no |
33+
| <a name="input_profile"></a> [profile](#input\_profile) | Profile of the OCM role to create. Allowed values are `standard`, `admin`, and `no-console`. | `string` | `"standard"` | no |
34+
35+
## Outputs
36+
37+
| Name | Description |
38+
| ---- | ----------- |
39+
| <a name="output_role_arn"></a> [role\_arn](#output\_role\_arn) | The ARN of the created OCM IAM role. |
40+
| <a name="output_role_link_id"></a> [role\_link\_id](#output\_role\_link\_id) | The identifier of the OCM-side role link. |
41+
| <a name="output_role_name"></a> [role\_name](#output\_role\_name) | The name of the created OCM IAM role. |
42+
<!-- END_AUTOMATED_TF_DOCS_BLOCK -->

examples/ocm-role/main.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright Red Hat
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
############################
5+
# OCM Role
6+
############################
7+
module "ocm_role" {
8+
source = "../../modules/ocm-role"
9+
10+
ocm_role_prefix = var.ocm_role_prefix
11+
profile = var.profile
12+
}

examples/ocm-role/outputs.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright Red Hat
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
output "role_arn" {
5+
value = module.ocm_role.role_arn
6+
description = "The ARN of the created OCM IAM role."
7+
}
8+
9+
output "role_name" {
10+
value = module.ocm_role.role_name
11+
description = "The name of the created OCM IAM role."
12+
}
13+
14+
output "role_link_id" {
15+
value = module.ocm_role.role_link_id
16+
description = "The identifier of the OCM-side role link."
17+
}

examples/ocm-role/variables.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright Red Hat
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
variable "ocm_role_prefix" {
5+
type = string
6+
description = "User-defined prefix for the OCM IAM role name."
7+
default = "ManagedOpenShift"
8+
}
9+
10+
variable "profile" {
11+
type = string
12+
description = "Profile of the OCM role to create. Allowed values are `standard`, `admin`, and `no-console`."
13+
default = "standard"
14+
}

examples/ocm-role/versions.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright Red Hat
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
terraform {
5+
required_version = ">= 1.0"
6+
7+
required_providers {
8+
aws = {
9+
source = "hashicorp/aws"
10+
version = ">= 6.0"
11+
}
12+
rhcs = {
13+
source = "terraform-redhat/rhcs"
14+
version = ">= 1.7.7"
15+
}
16+
}
17+
}

modules/ocm-role/README.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# ocm-role
2+
3+
## Introduction
4+
5+
This Terraform sub-module creates the AWS IAM OCM role with the tags required by the ROSA CLI and OCM. The role is used to grant OpenShift Cluster Manager permissions in the customer's AWS account.
6+
7+
The module creates the IAM role, attaches the appropriate permission policies for the selected profile, applies the required tags, and links the role to the current OCM organization via `rhcs_rosa_ocm_role_link`.
8+
9+
For more information, see [Understanding OCM role and User role for ROSA](https://access.redhat.com/articles/6961686).
10+
11+
## Example Usage
12+
13+
```
14+
module "ocm_role" {
15+
source = "terraform-redhat/rosa-hcp/rhcs//modules/ocm-role"
16+
version = "1.7.7"
17+
18+
ocm_role_prefix = "ManagedOpenShift"
19+
profile = "standard"
20+
}
21+
```
22+
23+
<!-- BEGIN_AUTOMATED_TF_DOCS_BLOCK -->
24+
## Requirements
25+
26+
| Name | Version |
27+
| ---- | ------- |
28+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
29+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
30+
| <a name="requirement_rhcs"></a> [rhcs](#requirement\_rhcs) | >= 1.7.7 |
31+
32+
## Providers
33+
34+
| Name | Version |
35+
| ---- | ------- |
36+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
37+
| <a name="provider_rhcs"></a> [rhcs](#provider\_rhcs) | >= 1.7.7 |
38+
39+
## Modules
40+
41+
No modules.
42+
43+
## Resources
44+
45+
| Name | Type |
46+
| ---- | ---- |
47+
| [aws_iam_policy.ocm_admin_permission_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
48+
| [aws_iam_policy.ocm_no_console_permission_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
49+
| [aws_iam_policy.standard_permission_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
50+
| [aws_iam_role.ocm_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
51+
| [aws_iam_role_policy_attachment.ocm_admin_permission_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
52+
| [aws_iam_role_policy_attachment.ocm_no_console_permission_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
53+
| [aws_iam_role_policy_attachment.standard_permission_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
54+
| [rhcs_rosa_ocm_role_link.this](https://registry.terraform.io/providers/terraform-redhat/rhcs/latest/docs/resources/rosa_ocm_role_link) | resource |
55+
| [rhcs_hcp_policies.all_policies](https://registry.terraform.io/providers/terraform-redhat/rhcs/latest/docs/data-sources/hcp_policies) | data source |
56+
| [rhcs_info.current](https://registry.terraform.io/providers/terraform-redhat/rhcs/latest/docs/data-sources/info) | data source |
57+
58+
## Inputs
59+
60+
| Name | Description | Type | Default | Required |
61+
| ---- | ----------- | ---- | ------- | :------: |
62+
| <a name="input_create_link"></a> [create\_link](#input\_create\_link) | (Optional) Whether to link the created role to the OCM organization via rhcs\_rosa\_ocm\_role\_link. Set to false when importing an already-linked role. | `bool` | `true` | no |
63+
| <a name="input_ocm_role_prefix"></a> [ocm\_role\_prefix](#input\_ocm\_role\_prefix) | User-defined prefix for the OCM IAM role name. The final role name is `<prefix>-OCM-Role-<organization_external_id>`. | `string` | n/a | yes |
64+
| <a name="input_path"></a> [path](#input\_path) | (Optional) The IAM path for the OCM role and its policies. Must begin and end with '/'. | `string` | `"/"` | no |
65+
| <a name="input_permissions_boundary"></a> [permissions\_boundary](#input\_permissions\_boundary) | (Optional) The ARN of the policy used to set the permissions boundary for the OCM IAM role. | `string` | `""` | no |
66+
| <a name="input_profile"></a> [profile](#input\_profile) | Profile of the OCM role to create. Allowed values are `standard`, `admin`, and `no-console`. | `string` | `"standard"` | no |
67+
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) Additional AWS resource tags to merge into the OCM role and its policies. | `map(string)` | `null` | no |
68+
69+
## Outputs
70+
71+
| Name | Description |
72+
| ---- | ----------- |
73+
| <a name="output_role_arn"></a> [role\_arn](#output\_role\_arn) | The ARN of the created OCM IAM role. |
74+
| <a name="output_role_link_id"></a> [role\_link\_id](#output\_role\_link\_id) | The identifier of the OCM-side role link created for the IAM role, or null when create\_link is false. |
75+
| <a name="output_role_name"></a> [role\_name](#output\_role\_name) | The name of the created OCM IAM role. |
76+
<!-- END_AUTOMATED_TF_DOCS_BLOCK -->

modules/ocm-role/main.tf

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright Red Hat
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
locals {
5+
path = coalesce(var.path, "/")
6+
7+
role_type = "OCM"
8+
role_suffix = "-${local.role_type}-Role-${data.rhcs_info.current.organization_external_id}"
9+
max_prefix_length = 64 - length(local.role_suffix)
10+
truncated_role_prefix = local.max_prefix_length > 0 ? substr(var.ocm_role_prefix, 0, local.max_prefix_length) : ""
11+
role_name = "${local.truncated_role_prefix}${local.role_suffix}"
12+
max_policy_name_length = 128
13+
standard_policy_enabled = contains(["standard", "admin"], var.profile)
14+
admin_policy_enabled = var.profile == "admin"
15+
no_console_enabled = var.profile == "no-console"
16+
17+
ocm_environment = (
18+
strcontains(data.rhcs_info.current.ocm_api, "api.stage.") ? "staging" :
19+
(
20+
strcontains(data.rhcs_info.current.ocm_api, "integration") || strcontains(data.rhcs_info.current.ocm_api, ".int.") ? "integration" : "production"
21+
)
22+
)
23+
24+
base_tags = merge(var.tags, {
25+
red-hat-managed = true
26+
rosa_role_prefix = var.ocm_role_prefix
27+
rosa_role_type = local.role_type
28+
rosa_environment = local.ocm_environment
29+
})
30+
31+
role_tags = local.admin_policy_enabled ? merge(local.base_tags, {
32+
rosa_admin_role = true
33+
}) : (
34+
local.no_console_enabled ? merge(local.base_tags, {
35+
rosa_no_console_role = true
36+
}) : local.base_tags
37+
)
38+
}
39+
40+
data "rhcs_hcp_policies" "all_policies" {}
41+
42+
data "rhcs_info" "current" {}
43+
44+
resource "aws_iam_role" "ocm_role" {
45+
name = local.role_name
46+
permissions_boundary = var.permissions_boundary
47+
path = local.path
48+
assume_role_policy = data.rhcs_hcp_policies.all_policies.ocm_role_policies.sts_ocm_trust_policy
49+
force_detach_policies = true
50+
51+
tags = local.role_tags
52+
}
53+
54+
resource "aws_iam_policy" "standard_permission_policy" {
55+
count = local.standard_policy_enabled ? 1 : 0
56+
57+
name = substr("${local.role_name}-Policy", 0, local.max_policy_name_length)
58+
path = local.path
59+
policy = data.rhcs_hcp_policies.all_policies.ocm_role_policies.sts_ocm_permission_policy
60+
61+
tags = local.base_tags
62+
}
63+
64+
resource "aws_iam_role_policy_attachment" "standard_permission_policy_attachment" {
65+
count = local.standard_policy_enabled ? 1 : 0
66+
67+
role = aws_iam_role.ocm_role.name
68+
policy_arn = aws_iam_policy.standard_permission_policy[0].arn
69+
}
70+
71+
resource "aws_iam_policy" "ocm_admin_permission_policy" {
72+
count = local.admin_policy_enabled ? 1 : 0
73+
74+
name = substr("${local.role_name}-Admin-Policy", 0, local.max_policy_name_length)
75+
path = local.path
76+
policy = data.rhcs_hcp_policies.all_policies.ocm_role_policies.sts_ocm_admin_permission_policy
77+
78+
tags = merge(local.base_tags, {
79+
rosa_admin_role = true
80+
})
81+
}
82+
83+
resource "aws_iam_role_policy_attachment" "ocm_admin_permission_policy_attachment" {
84+
count = local.admin_policy_enabled ? 1 : 0
85+
86+
role = aws_iam_role.ocm_role.name
87+
policy_arn = aws_iam_policy.ocm_admin_permission_policy[0].arn
88+
}
89+
90+
resource "aws_iam_policy" "ocm_no_console_permission_policy" {
91+
count = local.no_console_enabled ? 1 : 0
92+
93+
name = substr("${local.role_name}-NoConsole-Policy", 0, local.max_policy_name_length)
94+
path = local.path
95+
policy = data.rhcs_hcp_policies.all_policies.ocm_role_policies.sts_ocm_no_console_permission_policy
96+
97+
tags = merge(local.base_tags, {
98+
rosa_no_console_role = true
99+
})
100+
}
101+
102+
resource "aws_iam_role_policy_attachment" "ocm_no_console_permission_policy_attachment" {
103+
count = local.no_console_enabled ? 1 : 0
104+
105+
role = aws_iam_role.ocm_role.name
106+
policy_arn = aws_iam_policy.ocm_no_console_permission_policy[0].arn
107+
}
108+
109+
resource "rhcs_rosa_ocm_role_link" "this" {
110+
count = var.create_link ? 1 : 0
111+
112+
role_arn = aws_iam_role.ocm_role.arn
113+
}

modules/ocm-role/outputs.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright Red Hat
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
output "role_arn" {
5+
value = aws_iam_role.ocm_role.arn
6+
description = "The ARN of the created OCM IAM role."
7+
}
8+
9+
output "role_name" {
10+
value = aws_iam_role.ocm_role.name
11+
description = "The name of the created OCM IAM role."
12+
}
13+
14+
output "role_link_id" {
15+
value = try(rhcs_rosa_ocm_role_link.this[0].id, null)
16+
description = "The identifier of the OCM-side role link created for the IAM role, or null when create_link is false."
17+
}

0 commit comments

Comments
 (0)