×

Terraform is an infrastructure-as-code tool that provides a way to configure your resources once and replicate those resources as desired. Terraform accomplishes the creation tasks by using declarative language. You declare what you want the final state of the infrastructure resource to be, and Terraform creates these resources to your specifications.

Prerequisites for Terraform

To use the Red Hat Cloud Services provider inside your Terraform configuration, you must meet the following prerequisites:

  • You have installed the Red Hat OpenShift Service on AWS (ROSA) command-line interface (CLI) tool.

    See the Additional resources for further installation instructions.

  • You have your offline Red Hat OpenShift Cluster Manager token.

    This token is generated through the Red Hat Hybrid Cloud Console. It is unique to your account and should not be shared. The token is generated based off your account access and permissions.

  • You have installed Terraform version 1.4.6 or newer.

    You must have Terraform configured for your local system. The Terraform website contains installation options for MacOS, Windows, and Linux.

  • You have an AWS account and associated credentials that allow you to create resources. The credentials are configured for the AWS provider. See the Authentication and Configuration section in AWS Terraform provider documentation.

  • You have, at minimum, the following permissions in your AWS IAM role policy that is operating Terraform. Check for these permissions in the AWS console.

    Minimum AWS permissions for Terraform
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "VisualEditor0",
          "Effect": "Allow",
          "Action": [
            "iam:GetPolicyVersion",
            "iam:DeletePolicyVersion",
            "iam:CreatePolicyVersion",
            "iam:UpdateAssumeRolePolicy",
            "secretsmanager:DescribeSecret",
            "iam:ListRoleTags",
            "secretsmanager:PutSecretValue",
            "secretsmanager:CreateSecret",
            "iam:TagRole",
            "secretsmanager:DeleteSecret",
            "iam:UpdateOpenIDConnectProviderThumbprint",
            "iam:DeletePolicy",
            "iam:CreateRole",
            "iam:AttachRolePolicy",
            "iam:ListInstanceProfilesForRole",
            "secretsmanager:GetSecretValue",
            "iam:DetachRolePolicy",
            "iam:ListAttachedRolePolicies",
            "iam:ListPolicyTags",
            "iam:ListRolePolicies",
            "iam:DeleteOpenIDConnectProvider",
            "iam:DeleteInstanceProfile",
            "iam:GetRole",
            "iam:GetPolicy",
            "iam:ListEntitiesForPolicy",
            "iam:DeleteRole",
            "iam:TagPolicy",
            "iam:CreateOpenIDConnectProvider",
            "iam:CreatePolicy",
            "secretsmanager:GetResourcePolicy",
            "iam:ListPolicyVersions",
            "iam:UpdateRole",
            "iam:GetOpenIDConnectProvider",
            "iam:TagOpenIDConnectProvider",
            "secretsmanager:TagResource",
            "sts:AssumeRoleWithWebIdentity",
            "iam:ListRoles"
          ],
          "Resource": [
            "arn:aws:secretsmanager:*:<ACCOUNT_ID>:secret:*",
            "arn:aws:iam::<ACCOUNT_ID>:instance-profile/*",
            "arn:aws:iam::<ACCOUNT_ID>:role/*",
            "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/*",
            "arn:aws:iam::<ACCOUNT_ID>:policy/*"
          ]
        },
        {
          "Sid": "VisualEditor1",
          "Effect": "Allow",
          "Action": [
            "s3:*"
            ],
          "Resource": "*"
        }
      ]
    }

Considerations when using Terraform

In general, using Terraform to manage cloud resources should be done with the expectation that any changes should be done using the Terraform methodology. Use caution when using tools outside of Terraform, such as the AWS console or Red Hat console, to modify cloud resources created by Terraform. Using tools outside Terraform to manage cloud resources that are already managed by Terraform introduces configuration drift from your declared Terraform configuration.

For example, if you upgrade your Terraform-created cluster by using the Red Hat Hybrid Cloud Console, you need to reconcile your Terraform state before applying any forthcoming configuration changes. For more information, see Manage resources in Terraform state in the HashiCorp Developer documentation.

Additional resources

Account roles Terraform example

The following example shows how Terraform can be used to create your Amazon Web Services (AWS) Identity and Access Management (IAM) account roles for ROSA.

Do not modify Terraform state files. For more information, see Considerations when using Terraform

Procedure
  1. Check your AWS account for existing roles and policies by running the following command:

    $ rosa list account-roles
  2. In your terminal, run the following command to export your Red Hat OpenShift Cluster Manager token. This value must include the full OpenShift Cluster Manager token:

    $ export RHCS_TOKEN="<your_offline_token>"

    You can verify that your token is saved by running the following command:

    $ echo $RHCS_TOKEN

    You see your token in the command line.

  3. Optional: You can specify your own account-role prefix that prepends the roles you create by running the following command:

    If you do not specify an account-role prefix, a prefix is generated in the format of account-role- followed by a string of four random characters.

    $ export TF_VAR_account_role_prefix=<account_role_prefix>
  4. Create the Terraform files locally by using the following code templates:

    These files are created in your current directory. Ensure that you are in the directory where you want to run Terraform.

    1. The main.tf file calls the Red Hat Cloud Services Terraform provider, which allows you to use OpenShift services with Terraform. Run the following command to create the main.tf file:

      $ cat<<-EOF>main.tf
        #
        # Copyright (c) 2022 Red Hat, Inc.
        #
        # Licensed under the Apache License, Version 2.0 (the "License");
        # you may not use this file except in compliance with the License.
        # You may obtain a copy of the License at
        #
        #   http://www.apache.org/licenses/LICENSE-2.0
        #
        # Unless required by applicable law or agreed to in writing, software
        # distributed under the License is distributed on an "AS IS" BASIS,
        # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        # See the License for the specific language governing permissions and
        # limitations under the License.
        #
      
        terraform {
          required_providers {
            aws = {
              source  = "hashicorp/aws"
              version = ">= 4.20.0"
            }
            rhcs = {
              version = "1.4.0"
              source  = "terraform-redhat/rhcs"
            }
          }
        }
      
        data "rhcs_policies" "all_policies" {}
      
        data "rhcs_versions" "all" {}
      
        module "create_account_roles" {
          source  = "terraform-redhat/rosa-sts/aws"
          version = "0.0.15"
      
          create_operator_roles = false
          create_oidc_provider  = false
          create_account_roles  = true
      
          account_role_prefix    = var.account_role_prefix
          rosa_openshift_version = var.openshift_version
          account_role_policies  = data.rhcs_policies.all_policies.account_role_policies
          operator_role_policies = data.rhcs_policies.all_policies.operator_role_policies
          all_versions           = data.rhcs_versions.all
          tags                   = var.tags
        }
      EOF
    2. You define the account role prefix structure in the output.tf file. This output definition allows you to specify how the various generated roles are constructed. Run the following command to create your output.tf file:

      $ cat<<-EOF>output.tf
        output "account_role_prefix" {
          value = module.create_account_roles.account_role_prefix
        }
      EOF
    3. The variables.tf allows you to specify values you want for select variables. If you exported a variable for the account_role_prefix earlier, leave this variable’s default value blank. Setting the variable in both places with different values can produce unexpected results. Run the following command to create your variables.tf file:

      Do not include your OpenShift Cluster Manager token in this file if it is not stored in a safe location.

      $ cat<<-EOF>variables.tf
        variable "openshift_version" {
          type = string
          default = "4.13"
          description = "Enter the desired OpenShift version as X.Y. This version should match what you intend for your ROSA cluster. For example, if you plan to create a ROSA cluster using '4.13.10', then this version should be '4.13'. You can see the supported versions of OpenShift by running 'rosa list version'."
        }
      
        variable "account_role_prefix" {
          type    = string
          default = ""
          description = "Your account roles are prepended with whatever value you enter here. The default value in the ROSA CLI is 'ManagedOpenshift-' before all of your account roles."
        }
      
        variable "tags" { (1)
          type        = map
          default     = null
          description = "(Optional) List of AWS resource tags to apply."
        }
      EOF
      1 The tags parameter uses a map of strings variable. The format that it takes looks like the following example:
      variable "tags" {
        type    = "map"
        default = {
          "us-east-1" = "image-1234"
          "us-west-2" = "image-4567"
        }
      }
  5. In the directory where you saved these Terraform files, run the following command to set up Terraform to create these resources:

    $ terraform init
  6. Optional: Run the following command to confirm that the Terraform code you copied is correct:

    $ terraform validate
    Sample output
    Success! The configuration is valid.
  7. Optional: Test your Terraform template and create a reusable Terraform plan file by running the following command:

    $ terraform plan -out account-roles.tfplan
  8. Run the following command to build your account-wide IAM roles with Terraform:

    $ terraform apply "account-roles.tfplan"

    If you used the terraform plan command first, you can provide your created account-roles.tf file here. Otherwise, Terraform temporarily creates this plan before it applies your desired outcome.

Verification
  • Run the following command to verify that your account-roles have been created:

    $ rosa list account-roles
    Sample output
    I: Fetching account roles
    ROLE NAME                            ROLE TYPE      ROLE ARN                                                            OPENSHIFT VERSION  AWS Managed
    account-role-6kn4-ControlPlane-Role  Control plane  arn:aws:iam::269733383066:role/account-role-6kn4-ControlPlane-Role  4.13               No
    account-role-6kn4-Installer-Role     Installer      arn:aws:iam::269733383066:role/account-role-6kn4-Installer-Role     4.13               No
    account-role-6kn4-Support-Role       Support        arn:aws:iam::269733383066:role/account-role-6kn4-Support-Role       4.13               No
    account-role-6kn4-Worker-Role        Worker         arn:aws:iam::269733383066:role/account-role-6kn4-Worker-Role        4.13               No
Clean up

When you are finished using the resources that you created using Terraform, you should purge these resources with the following command:

$ terraform destroy