Skip to content

Commit 7b924fe

Browse files
olucasfreitasmichaelryanmcneill
authored andcommitted
ROSAENG-6809 | feat: align OCM role module with reviewer-approved HCP shape
Rework the classic OCM role implementation to match the reviewer-approved shape from terraform-rhcs-rosa-hcp PR #154. The OCM role is now a standalone module and example rather than a root cluster-module feature. The module derives organization metadata and environment from rhcs_info, uses the released rhcs_hcp_policies data source, creates direct AWS IAM resources, supports standard/admin/ no-console profiles, and creates the rhcs_rosa_ocm_role_link internally. This also adds module-level Terraform tests, a standalone examples/ ocm-role surface, bumps the RHCS provider floor to 1.7.7, and updates docs to match the new standalone created-and-linked OCM role flow. Signed-off-by: lufreita <lufreita@redhat.com>
1 parent 264d9d5 commit 7b924fe

13 files changed

Lines changed: 732 additions & 2 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Sub-modules included in this module:
2626

2727
- [account-iam-resources](./modules/account-iam-resources): Handles the provisioning of IAM (Identity and Access Management) resources required for managing access and permissions in the AWS account associated with the ROSA Classic cluster.
2828
- [idp](./modules/idp): Responsible for configuring Identity Providers (IDPs) within the ROSA Classic cluster, facilitating seamless integration with external authentication systems such as GitHub, GitLab, Google, HTPasswd, LDAP, and OpenID Connect (OIDC).
29+
- [ocm-role](./modules/ocm-role): Creates and links the AWS IAM OCM role with the required ROSA CLI-parity naming, tagging, trust policy, and permission policies.
2930
- [machine-pool](./modules/machine-pool): Facilitates the management of machine pools within the ROSA Classic cluster, enabling users to scale resources and adjust specifications based on workload demands.
3031
- [oidc-config-and-provider](./modules/oidc-config-and-provider): Manages the configuration of OIDC (OpenID Connect) providers within the ROSA Classic cluster, enabling secure authentication and access control mechanisms.
3132
- [operator-policies](./modules/operator-policies): Responsible for managing policies associated with ROSA operators within the cluster, ensuring proper permissions for core cluster functionalities.
@@ -68,7 +69,7 @@ We recommend you install the following CLI tools:
6869
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.7 |
6970
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.0 |
7071
| <a name="requirement_null"></a> [null](#requirement\_null) | >= 3.3.0 |
71-
| <a name="requirement_rhcs"></a> [rhcs](#requirement\_rhcs) | >= 1.7.6 |
72+
| <a name="requirement_rhcs"></a> [rhcs](#requirement\_rhcs) | >= 1.7.7 |
7273

7374
## Providers
7475

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: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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-classic/rhcs//modules/ocm-role"
16+
17+
ocm_role_prefix = "ManagedOpenShift"
18+
profile = "standard"
19+
}
20+
```
21+
22+
<!-- BEGIN_AUTOMATED_TF_DOCS_BLOCK -->
23+
## Requirements
24+
25+
| Name | Version |
26+
| ---- | ------- |
27+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
28+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 6.0 |
29+
| <a name="requirement_rhcs"></a> [rhcs](#requirement\_rhcs) | >= 1.7.7 |
30+
31+
## Providers
32+
33+
| Name | Version |
34+
| ---- | ------- |
35+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 6.0 |
36+
| <a name="provider_rhcs"></a> [rhcs](#provider\_rhcs) | >= 1.7.7 |
37+
38+
## Modules
39+
40+
No modules.
41+
42+
## Resources
43+
44+
| Name | Type |
45+
| ---- | ---- |
46+
| [aws_iam_policy.ocm_admin_permission_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
47+
| [aws_iam_policy.ocm_no_console_permission_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
48+
| [aws_iam_policy.standard_permission_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
49+
| [aws_iam_role.ocm_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
50+
| [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 |
51+
| [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 |
52+
| [aws_iam_role_policy_attachment.standard_permission_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
53+
| [rhcs_rosa_ocm_role_link.this](https://registry.terraform.io/providers/terraform-redhat/rhcs/latest/docs/resources/rosa_ocm_role_link) | resource |
54+
| [rhcs_hcp_policies.all_policies](https://registry.terraform.io/providers/terraform-redhat/rhcs/latest/docs/data-sources/hcp_policies) | data source |
55+
| [rhcs_info.current](https://registry.terraform.io/providers/terraform-redhat/rhcs/latest/docs/data-sources/info) | data source |
56+
57+
## Inputs
58+
59+
| Name | Description | Type | Default | Required |
60+
| ---- | ----------- | ---- | ------- | :------: |
61+
| <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 |
62+
| <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 |
63+
| <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 |
64+
| <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 |
65+
| <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 |
66+
| <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 |
67+
68+
## Outputs
69+
70+
| Name | Description |
71+
| ---- | ----------- |
72+
| <a name="output_role_arn"></a> [role\_arn](#output\_role\_arn) | The ARN of the created OCM IAM role. |
73+
| <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. |
74+
| <a name="output_role_name"></a> [role\_name](#output\_role\_name) | The name of the created OCM IAM role. |
75+
<!-- 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)