Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
Merge pull request #61 from bardielle/fix_account_prefix
Browse files Browse the repository at this point in the history
Creating a new data source for ROSA operator IAM roles
  • Loading branch information
bardielle authored Nov 30, 2022
2 parents 0a1cdde + e9a3d61 commit 6b093b5
Show file tree
Hide file tree
Showing 29 changed files with 955 additions and 503 deletions.
47 changes: 10 additions & 37 deletions examples/create_rosa_cluster/create_rosa_sts_cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -37,42 +37,11 @@ locals {
sts_roles = {
role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/ManagedOpenShift-Installer-Role",
support_role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/ManagedOpenShift-Support-Role",
operator_iam_roles = [
{
name = "cloud-credential-operator-iam-ro-creds",
namespace = "openshift-cloud-credential-operator",
role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.operator_role_prefix}-openshift-cloud-credential-operator-cloud-c",
},
{
name = "installer-cloud-credentials",
namespace = "openshift-image-registry",
role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.operator_role_prefix}-openshift-image-registry-installer-cloud-cr",
},
{
name = "cloud-credentials",
namespace = "openshift-ingress-operator",
role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.operator_role_prefix}-openshift-ingress-operator-cloud-credential",
},
{
name = "ebs-cloud-credentials",
namespace = "openshift-cluster-csi-drivers",
role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.operator_role_prefix}-openshift-cluster-csi-drivers-ebs-cloud-cre",
},
{
name = "cloud-credentials",
namespace = "openshift-cloud-network-config-controller",
role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.operator_role_prefix}-openshift-cloud-network-config-controller-c",
},
{
name = "aws-cloud-credentials",
namespace = "openshift-machine-api",
role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${var.operator_role_prefix}-openshift-machine-api-aws-cloud-credentials",
},
]
instance_iam_roles = {
master_role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/ManagedOpenShift-ControlPlane-Role",
worker_role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/ManagedOpenShift-Worker-Role"
},
},
operator_role_prefix = var.operator_role_prefix,
}
}

Expand All @@ -90,13 +59,17 @@ resource "ocm_cluster_rosa_classic" "rosa_sts_cluster" {
sts = local.sts_roles
}

data "ocm_rosa_operator_roles" "operator_roles" {
cluster_id = ocm_cluster_rosa_classic.rosa_sts_cluster.id
operator_role_prefix = var.operator_role_prefix
account_role_prefix = var.account_role_prefix
}

module operator_roles {
source = "git::https://github.com/openshift-online/terraform-provider-ocm.git//modules/operator_roles"
source = "git::https://github.com/openshift-online/terraform-provider-ocm.git//modules/aws_roles"

cluster_id = ocm_cluster_rosa_classic.rosa_sts_cluster.id
operator_role_prefix = var.operator_role_prefix
account_role_prefix = var.account_role_prefix
rh_oidc_provider_thumbprint = ocm_cluster_rosa_classic.rosa_sts_cluster.sts.thumbprint
rh_oidc_provider_url = ocm_cluster_rosa_classic.rosa_sts_cluster.sts.oidc_endpoint_url

operator_roles_properties = data.ocm_rosa_operator_roles.operator_roles.operator_iam_roles
}
15 changes: 15 additions & 0 deletions examples/create_rosa_cluster/create_rosa_sts_cluster/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
output operator_iam_roles {
value = data.ocm_rosa_operator_roles.operator_roles.operator_iam_roles
}

output cluster_id {
value = ocm_cluster_rosa_classic.rosa_sts_cluster.id
}

output rh_oidc_provider_thumbprint {
value = ocm_cluster_rosa_classic.rosa_sts_cluster.sts.thumbprint
}

output rh_oidc_provider_url {
value = ocm_cluster_rosa_classic.rosa_sts_cluster.sts.oidc_endpoint_url
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ variable operator_role_prefix {

variable account_role_prefix {
type = string
default = ""
}

variable url {
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/openshift-online/terraform-provider-ocm
go 1.17

require (
github.com/hashicorp/go-version v1.3.0
github.com/hashicorp/terraform-plugin-framework v0.5.0
github.com/hashicorp/terraform-plugin-go v0.5.0
github.com/onsi/ginkgo/v2 v2.1.4
Expand Down Expand Up @@ -69,4 +70,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/openshift-online/ocm-sdk-go v0.1.240 => github.com/openshift-online/ocm-sdk-go v0.1.275
replace github.com/openshift-online/ocm-sdk-go => github.com/openshift-online/ocm-sdk-go v0.1.275
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ github.com/hashicorp/go-plugin v1.4.1/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ3
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/terraform-plugin-framework v0.5.0 h1:QUBNSZHiRJrQpbjqCdPcw5MRLU1TyzpQCrA4eRId364=
Expand Down
File renamed without changes.
177 changes: 177 additions & 0 deletions modules/aws_roles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# operator role module

Create rosa operator roles and identity provider in an declarative way
Terraform AWS ROSA STS Roles

In order to deploy [ROSA](https://docs.openshift.com/rosa/welcome/index.html) with [STS](https://docs.openshift.com/rosa/rosa_planning/rosa-sts-aws-prereqs.html), AWS Account needs to have the following roles placed:

* Account Roles (One per AWS account)
* OCM Roles (For OCM UI, One per OCM Org)
* User Role (For OCM UI, One per OCM user account)
* Operator Roles (One Per Cluster)
* OIDC Identity Provider (One Per Cluster)

This terraform module tries to replicate rosa CLI roles creation so that:

* Users have a declartive way to create AWS roles.
* Users can implement security/infrastructure as code practices.
* Batch creation of operator roles.

## Prerequisites

* AWS Admin Account configured by using AWS CLI in AWS configuration file
* OCM Account and OCM CLI
* ROSA CLI

## Get OCM Information

When creating operator IAM roles, the roles require cluster id, operator role prefix, OIDC endpoint url and thumbprint


The information can be retrieved from ocm cli.
```
ocm whoami
{
"kind": "Account",
"id": "26kcPSEHi0Y6MkTS7OowxfFYmZo",
"href": "/api/accounts_mgmt/v1/accounts/26kcPSEHi0Y6MkTS7OowxfFYmZo",
"created_at": "2022-03-22T17:43:19Z",
"email": "[email protected]",
"first_name": "Shaozhen",
"last_name": "Ding",
"organization": {
"kind": "Organization",
"id": "1rkxPO7W12geIcRWITwI0I8VIQV",
"href": "/api/accounts_mgmt/v1/organizations/1rkxPO7W12geIcRWITwI0I8VIQV",
"created_at": "2021-04-27T14:31:03Z",
"ebs_account_id": "7113273",
"external_id": "14540493",
"name": "Red Hat, Inc.",
"updated_at": "2022-06-16T14:17:02Z"
},
"updated_at": "2022-05-25T02:02:02Z",
"username": "shading_mobb"
}
```

## Get Clusters Information.

In order to create operator roles for clusters.
Users need to provide cluster id, OIDC Endpoint URL and thumbprint and operator roles properties list.

```
rosa describe cluster -c shaozhenprivate -o json
{
"kind": "Cluster",
"id": "1srtno3qggal8ujsegvtb2njvbmhdu8c",
"href": "/api/clusters_mgmt/v1/clusters/1srtno3qggal8ujsegvtb2njvbmhdu8c",
"aws": {
"sts": {
"oidc_endpoint_url": "https://rh-oidc.s3.us-east-1.amazonaws.com/1srtno3qggal8ujsegvtb2njvbmhdu8c",
"operator_iam_roles": [
{
"id": "",
"name": "ebs-cloud-credentials",
"namespace": "openshift-cluster-csi-drivers",
"role_arn": "arn:aws:iam::${AWS_ACCOUNT_ID}:role/shaozhenprivate-w4e1-openshift-cluster-csi-drivers-ebs-cloud-cre",
"service_account": ""
},
```

In the above example:

* cluster_id = 1srtno3qggal8ujsegvtb2njvbmhdu8c
* operator_role_prefix = shaozhenprivate-w4e1
* account_role_prefix = ManagedOpenShift
* rh_oidc_endpoint_url = rh-oidc.s3.us-east-1.amazonaws.com
* thumberprint - calculated


The operator roles properties variable is the output of the data source `ocm_rosa_operator_roles` and it's a list of 6 maps which looks like:
```
operator_iam_roles = [
{
"operator_name" = "cloud-credentials"
"operator_namespace" = "openshift-ingress-operator"
"policy_name" = "ManagedOpenShift-openshift-ingress-operator-cloud-credentials"
"role_arn" = "arn:aws:iam::765374464689:role/terrafom-operator-openshift-ingress-operator-cloud-credentials"
"role_name" = "terrafom-operator-openshift-ingress-operator-cloud-credentials"
"service_accounts" = [
"system:serviceaccount:openshift-ingress-operator:ingress-operator",
]
},
{
"operator_name" = "ebs-cloud-credentials"
"operator_namespace" = "openshift-cluster-csi-drivers"
"policy_name" = "ManagedOpenShift-openshift-cluster-csi-drivers-ebs-cloud-credent"
"role_arn" = "arn:aws:iam::765374464689:role/terrafom-operator-openshift-cluster-csi-drivers-ebs-cloud-creden"
"role_name" = "terrafom-operator-openshift-cluster-csi-drivers-ebs-cloud-creden"
"service_accounts" = [
"system:serviceaccount:openshift-cluster-csi-drivers:aws-ebs-csi-driver-operator",
"system:serviceaccount:openshift-cluster-csi-drivers:aws-ebs-csi-driver-controller-sa",
]
},
{
"operator_name" = "cloud-credentials"
"operator_namespace" = "openshift-cloud-network-config-controller"
"policy_name" = "ManagedOpenShift-openshift-cloud-network-config-controller-cloud"
"role_arn" = "arn:aws:iam::765374464689:role/terrafom-operator-openshift-cloud-network-config-controller-clou"
"role_name" = "terrafom-operator-openshift-cloud-network-config-controller-clou"
"service_accounts" = [
"system:serviceaccount:openshift-cloud-network-config-controller:cloud-network-config-controller",
]
},
{
"operator_name" = "aws-cloud-credentials"
"operator_namespace" = "openshift-machine-api"
"policy_name" = "ManagedOpenShift-openshift-machine-api-aws-cloud-credentials"
"role_arn" = "arn:aws:iam::765374464689:role/terrafom-operator-openshift-machine-api-aws-cloud-credentials"
"role_name" = "terrafom-operator-openshift-machine-api-aws-cloud-credentials"
"service_accounts" = [
"system:serviceaccount:openshift-machine-api:machine-api-controllers",
]
},
{
"operator_name" = "cloud-credential-operator-iam-ro-creds"
"operator_namespace" = "openshift-cloud-credential-operator"
"policy_name" = "ManagedOpenShift-openshift-cloud-credential-operator-cloud-crede"
"role_arn" = "arn:aws:iam::765374464689:role/terrafom-operator-openshift-cloud-credential-operator-cloud-cred"
"role_name" = "terrafom-operator-openshift-cloud-credential-operator-cloud-cred"
"service_accounts" = [
"system:serviceaccount:openshift-cloud-credential-operator:cloud-credential-operator",
]
},
{
"operator_name" = "installer-cloud-credentials"
"operator_namespace" = "openshift-image-registry"
"policy_name" = "ManagedOpenShift-openshift-image-registry-installer-cloud-creden"
"role_arn" = "arn:aws:iam::765374464689:role/terrafom-operator-openshift-image-registry-installer-cloud-crede"
"role_name" = "terrafom-operator-openshift-image-registry-installer-cloud-crede"
"service_accounts" = [
"system:serviceaccount:openshift-image-registry:cluster-image-registry-operator",
"system:serviceaccount:openshift-image-registry:registry",
]
},
]
```
## Usage

### Sample Usage

```
data "ocm_rosa_operator_roles" "operator_roles" {
cluster_id = ocm_cluster_rosa_classic.rosa_sts_cluster.id
operator_role_prefix = var.operator_role_prefix
account_role_prefix = var.account_role_prefix
}
module operator_roles {
source = "git::https://github.com/openshift-online/terraform-provider-ocm.git//modules/operator_roles"
cluster_id = ocm_cluster_rosa_classic.rosa_sts_cluster.id
rh_oidc_provider_thumbprint = ocm_cluster_rosa_classic.rosa_sts_cluster.sts.thumbprint
rh_oidc_provider_url = ocm_cluster_rosa_classic.rosa_sts_cluster.sts.oidc_endpoint_url
operator_roles_properties = data.ocm_rosa_operator_roles.operator_roles.operator_iam_roles
}
```
19 changes: 19 additions & 0 deletions modules/aws_roles/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}

module rosa_operator_roles {
source = "./operator_roles"
count = 6

cluster_id = var.cluster_id
rh_oidc_provider_url = var.rh_oidc_provider_url
rh_oidc_provider_thumbprint = var.rh_oidc_provider_thumbprint
operator_role_properties = var.operator_roles_properties[count.index]
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
resource "aws_iam_role" "machine_api_role" {
name = "${var.operator_role_prefix}-openshift-machine-api-aws-cloud-credentials"
data "aws_caller_identity" "current" {}

resource "aws_iam_role" "operator_role" {
name = var.operator_role_properties.role_name
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
Expand All @@ -8,7 +10,7 @@ resource "aws_iam_role" "machine_api_role" {
Effect = "Allow"
Condition = {
StringEquals = {
"${var.rh_oidc_provider_url}:sub" = ["system:serviceaccount:openshift-machine-api:machine-api-controllers"]
"${var.rh_oidc_provider_url}:sub" = var.operator_role_properties.service_accounts
}
}
Principal = {
Expand All @@ -21,12 +23,13 @@ resource "aws_iam_role" "machine_api_role" {
tags = {
red-hat-managed = true
rosa_cluster_id = var.cluster_id
operator_namespace = "openshift-machine-api"
operator_name = "aws-cloud-credentials"
operator_namespace = var.operator_role_properties.operator_namespace
operator_name = var.operator_role_properties.operator_name
}
}

resource "aws_iam_role_policy_attachment" "machine_api_role_policy_attachment" {
role = aws_iam_role.machine_api_role.name
policy_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/${var.account_role_prefix}-openshift-machine-api-aws-cloud-credentials"
}
resource "aws_iam_role_policy_attachment" "operator_role_policy_attachment" {
role = aws_iam_role.operator_role.name
policy_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy/${var.operator_role_properties.policy_name}"
}

29 changes: 29 additions & 0 deletions modules/aws_roles/operator_roles/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
variable cluster_id {
description = "cluster ID"
type = string
}

variable rh_oidc_provider_url {
description = "oidc provider url"
type = string
default = "rh-oidc.s3.us-east-1.amazonaws.com"
}

variable rh_oidc_provider_thumbprint {
description = "Thumbprint for the variable `rh_oidc_provider_url`"
type = string
default = "917e732d330f9a12404f73d8bea36948b929dffc"
}

variable operator_role_properties {
description = ""
type = object({
role_name = string
policy_name = string
service_accounts = list(string)
operator_name = string
operator_namespace = string
role_arn = string
})

}
Loading

0 comments on commit 6b093b5

Please sign in to comment.