Blueprinting the Onboarding of Cloud Projects Using Terraform

5 min read

Best practices for the cloud onboarding of enterprise projects.

Recently, I blogged about getting insights into IBM Cloud access privileges. Today, we are going to put them into practice. When onboarding a new project — either on-prem or to a cloud environment — there should be no questions on how to get started. Onboarding should follow an enterprise-defined process based on (internal) standards. It needs to detail access roles and privileges and provide means to implement them.

In this blog, I am going to discuss such a project onboarding. Terraform scripts implement the rules as code — they help to automate roll-out and tear down access roles and privileges. The scenario from the solution tutorial "Apply end-to-end security to a cloud application" serves as specific example to proof-point the ideas.

Overview

In an enterprise, onboarding a new project to a cloud environment should be a daily routine and follow a corporate standard. Quite often, unfortunately, this is not the case. Things to consider range from account ownership and billing over resource and access management to enforcing regulatory compliance via controls and audit. In this blog, we will briefly touch on all of those aspects, but focus on account setup for resource and access management.

Account or enterprise

As a typical user, you are working in an IBM Cloud account. However, corporations can use so-called enterprises to centrally manage billing and resource usage across many accounts. Enterprises can be organized into account groups and accounts on multiple levels. Thereby, they can mimic corporate organizational structures. Large customers could map a new cloud project to an account within an enterprise. In the extreme, each environment for a project (e.g., development, test, production) could be mapped to its own account inside the enterprise.

Within an account, resources can be organized in resource groups. They provide a means to separate resources for different tasks, environments, and project groups. If working with a single IBM Cloud account only, resource groups are the way to organize projects and their assets.

Users, service IDs, and access groups

As mentioned, as a typical user, you are working in an IBM Cloud account. If you are not the owner, you have been invited to it. Another type of identity is a service ID. It is created in an account, usually to represent an application or service. Both users and service IDs can be added to access groups. Access groups are used to bundle a set of privileges (access policies) for easier administration. In that sense, access groups are similar to security roles (i.e., each access group could define a role in the cloud development project).

Private catalogs

Depending on their assigned privileges, users and service IDs are capable of provisioning resources. To define the set of available services, administrators can set up private catalogs. A private catalog holds a subset of what is available in the IBM Cloud (public) catalog. It can be defined for an individual account or on the enterprise level. Moreover, it is possible to add products to a private catalog. 

Common account setup

In order to get started with a new project, a common set of structural objects should be rolled out:

  • Access groups to mimic roles in the development project (e.g., security admins, network admins, developer, DevOps, billing, audit, etc).
  • Resource groups to organize resources for deployment stages like development, test, or production environments.

The base setup is easily deployed using Terraform scripts. The sources are managed in a corporate, version-controlled repository. To adapt the common skeleton to the specific project, parameters are used. Thus, all projects follow a corporate standard which is managed as infrastructure as code/deployment as code (e.g., as Terraform scripts).

The following Terraform snippet shows how the access group for organization admins is created and how access policies are assigned. See this GitHub repository for the full code sample.

# create the Access Group
resource "ibm_iam_access_group" "cloud-organization-admins" {
  name = "${var.basename}-organization-admins"
  description = "Organize the structure of the resources used by the organization."
}

# Account Management > All Account Management Services: Administrator
resource "ibm_iam_access_group_policy" "cloud-organization-admins-org_admin" {
  access_group_id = ibm_iam_access_group.cloud-organization-admins.id
  account_management = true
  roles = [ "Administrator" ]
}

# IAM services > All Identity and Access enabled services: Administrator, Manager
resource "ibm_iam_access_group_policy" "cloud-organization-admins-iam_admin" {
  access_group_id = ibm_iam_access_group.cloud-organization-admins.id
  roles = [ "Administrator", "Manager" ]
}

# Account Management > Support Center: Editor to all groups
resource "ibm_iam_access_group_policy" "cloud-organization-admins-support" {
  access_group_id = ibm_iam_access_group.cloud-organization-admins.id
  roles = [ "Editor" ]
  resources {
    service = "support"
  }
}

Project adaption

With the common access groups and resource groups in place, the account setup can be adapted to the project requirements. Typically, even for fresh development projects, some resources need to be deployed. These could be database or security services, cloud object storage, or toolchains.

For this blog, I picked the solution tutorial on applying end-to-end security to a cloud app as sample project. Its architecture is depicted below:

Architecture diagram: End-to-end security for a cloud app.

Architecture diagram: End-to-end security for a cloud app.

On top of the general account setup, the following is deployed as either account owner or (super) administrator:

  • Set up a service ID for each access group to be used for creating resources.
  • Set up an API key per service ID so that the resources can be deployed (in Terraform).
  • Set up an additional access group to manage privileges for all application-related resources.
  • Optionally, remove unused access groups.
  • Adapt existing access groups to project requirements. This is mainly to add more privileges (access policies) so that roles (access groups) can manage or view project-specific resources.
  • Optionally, adapt some configuration to the deployment region. This could be for additional compliance requirements, naming conventions, or other reasons.
  • Invite project members as users to the account, directly assigning them access groups based on their project role(s).

Once the above project-specific extra layer is in place, additional resources can be created. In contrast to above, the new service IDs and their API keys are utilized to roll out the resources access group by access group. In the case of my example, it includes deploying common security services like the Cloud Activity Tracker or Certificate Manager using the security admin service ID. Moreover, application services like Key Protect for IBM Cloud (including root keys), IBM Cloud App ID, IBM Cloudant, and IBM Cloud Object Storage are created by the new service ID for application resources.

The following Terraform code sample from the GitHub repository shows how to deploy the Key Protect and Cloud Object Storage (COS) services, create a new root key, and use it for a new storage bucket. It also requires you to define the service authorizations.

# Key Protect
resource "ibm_resource_instance" "keyprotect" {
  name              = "${var.basename}-kp"
  service           = "kms"
  plan              = "tiered-pricing"
  location          = var.region
  resource_group_id = data.ibm_resource_group.cloud_development.id
  service_endpoints = "private"
}

# Cloud Object Storage (COS)
resource "ibm_resource_instance" "cos" {
  name              = "${var.basename}-cos"
  service           = "cloud-object-storage"
  plan              = "standard"
  location          = "global"
  resource_group_id = data.ibm_resource_group.cloud_development.id
}

# create root key in Key Protect
resource "ibm_kp_key" "rootkey" {
  key_protect_id = ibm_resource_instance.keyprotect.guid
  key_name       = "${var.basename}-rootkey"
  standard_key   = false
  force_delete   = true
}

# Authorization policies between services KP and COS
resource "ibm_iam_authorization_policy" "COSKMSpolicy" {
  source_service_name      = "cloud-object-storage"
  source_resource_group_id = data.ibm_resource_group.cloud_development.id
  target_service_name      = "kms"
  target_resource_group_id = data.ibm_resource_group.cloud_development.id
  roles                    = ["Reader"]
}

# create encrypted COS bucket using that root key
resource "ibm_cos_bucket" "cosbucket" {
  bucket_name          = "${var.basename}-bucket-${ibm_resource_instance.cos.guid}"
  resource_instance_id = ibm_resource_instance.cos.id
  region_location      = var.region
  key_protect          = ibm_kp_key.rootkey.crn
  storage_class        = "standard"
}

Conclusions

As mentioned at the beginning of this post, there should be no questions on how to get started when onboarding a new (cloud) project – it should follow an enterprise-defined process. In this blog, I introduced such a process. It starts with a new account and the corporate base layer. Thereafter, a project-specific layer is deployed which follows a defined pattern. Last, using new role-based service IDs, resources for the application or project are deployed.

Here are my lessons learned from such a project:

  • Automated, cascaded deployments are possible. Using Terraform, deployments are handled as code and managed as such.
  • Design a common blueprint for all projects, then customize it for specific projects. It simplifies the overall project management and enhances security.
  • Identity and Access Management (IAM) differs between cloud providers. Invest time to understand the IAM concepts.
  • Keep a Zero Trust Architecture in mind and design the blueprints for a least privilege model.

If you have feedback, suggestions, or questions about this post, please reach out to me on Twitter (@data_henrik) or LinkedIn

Be the first to hear about news, product updates, and innovation from IBM Cloud