Leveraging Terraform for Enhanced Asset Security with Mondoo - Part 3: Imports


Bicycle

In the previous posts of this blog series, we introduced the Mondoo platform, its Terraform provider resources and data sources, exploring how they enhance asset security and compliance. In this third part, we'll delve into an essential feature of Terraform - imports. Understanding Terraform imports is crucial for integrating existing infrastructure into your Terraform state, allowing you to manage your resources more effectively using Terraform's powerful IaC (Infrastructure as Code) capabilities.

What are Terraform Imports?

Terraform imports enable you to bring existing infrastructure under Terraform management. This process involves importing the current state of your infrastructure resources into your Terraform state file, allowing you to manage and track these resources as if they were created by Terraform from the beginning. This capability is invaluable for organizations transitioning to Terraform or those managing resources created outside of Terraform.

Why Use Terraform Imports?

  • Seamless Integration: Easily incorporate pre-existing resources into your Terraform configurations without needing to recreate them.
  • Unified Management: Maintain and manage all infrastructure resources from a single Terraform configuration.
  • Change Tracking: Leverage Terraform’s state management and plan capabilities to track changes and manage the lifecycle of imported resources.

How to Use Terraform Imports

To import a resource, we typically follow these steps:

  • Identify the Resource: Determine the resource and its corresponding Terraform resource type.
  • Define the Resource Configuration: Add the resource configuration to your Terraform files.
  • Execute the Import Command: Use the terraform import command to bring the resource into your state file.
  • Update the Resource Configuration: After importing the resource, update the values in your Terraform files with the actual values in the state to ensure consistency.

As of July 2024 many resources have received an import integration thanks to our cooperation with the Mondoo Team.

Step-by-Step Guide to Importing Resources

Let’s walk through the process of importing an existing resource into Terraform using the Mondoo Terraform provider.

Example: Importing an AWS Integration

Identify the Resource: Suppose you have an existing AWS integration in Mondoo that you need to manage using Terraform. We need to get its identifier. For Mondoo resources, this is called the MRN and can easily be retrieved from the UI:

MRN

Define the Resource Configuration: Before we import, we need to create a Terraform file (e.g. main.tf) containing the Mondoo Provider and the resource configuration. We can leave the actual values empty since we will get them after executing the import command:

 1terraform {
 2  required_providers {
 3    mondoo = {
 4      source  = "mondoohq/mondoo"
 5      version = ">= 0.4.0"
 6    }
 7  }
 8}
 9
10provider "mondoo" {}
11
12resource "mondoo_integration_aws" "example_integration" {
13  space_id = ""
14  name     = ""
15
16  credentials = {
17    key = {
18      access_key = ""
19      secret_key = ""
20    }
21  }
22}

Execute the Import Command:

1terraform import mondoo_integration_aws.example_integration [RESOURCE_ID]

Replace [RESOURCE_ID] with the actual ID of your AWS integration.

Update the Resource Configuration: After the import, have a look at the state file and fill in the correct values in the main.tf file to ensure consistency when working with the resource in the future:

 1terraform {
 2  required_providers {
 3    mondoo = {
 4      source  = "mondoohq/mondoo"
 5      version = ">= 0.4.0"
 6    }
 7  }
 8}
 9
10provider "mondoo" {}
11
12resource "mondoo_integration_aws" "example_integration" {
13  space_id = "the space id found inside the .tfstate file"
14  name     = "the name found inside the .tfstate file"
15
16  credentials = {
17    key = {
18      access_key = "the ACCESS_KEY found inside the .tfstate file"
19      secret_key = "you will not be able to find this in the .tfstate file"
20    }
21  }
22}

As you may have noticed, not all values can be found within the .tfstate file. In this case we will not be able to get the secret_key since it is a sensitive value.

Example: Importing a Google Cloud Platform (GCP) Integration

Identify the Resource: Assume we have an existing GCP integration set up in Mondoo that we want to manage with Terraform. We need to get its identifier like we did for the AWS Integration.

Define the Resource Configuration: Before we import, we need to create a Terraform file (e.g. main.tf) containing the Mondoo Provider and the resource configuration. We can leave the actual values empty since we will get them after executing the import command:

 1terraform {
 2  required_providers {
 3    mondoo = {
 4      source  = "mondoohq/mondoo"
 5      version = ">= 0.4.0"
 6    }
 7  }
 8}
 9
10provider "mondoo" {}
11
12resource "mondoo_integration_gcp" "example_integration" {
13  space_id   = ""
14  name       = ""
15  project_id = ""
16  credentials = {
17    private_key = ""
18  }
19}

Execute the Import Command:

1terraform import mondoo_integration_gcp.example_integration [RESOURCE_ID]

Replace [RESOURCE_ID] with the actual ID of your GCP integration.

Update the Resource Configuration: After the import, have a look at the state file and fill in the correct values in the main.tf file to ensure consistency when working with the resource in the future:

 1terraform {
 2  required_providers {
 3    mondoo = {
 4      source  = "mondoohq/mondoo"
 5      version = ">= 0.4.0"
 6    }
 7  }
 8}
 9
10provider "mondoo" {}
11
12resource "mondoo_integration_gcp" "example_integration" {
13  space_id   = "the space id found inside the .tfstate file"
14  name       = "the name found inside the .tfstate file
15  project_id = "the project id found inside the .tfstate file"
16  credentials = {
17    private_key = "you will not be able to find this in the .tfstate file"
18  }
19}

Just like in the AWS integration, the GCP integration contains certain sensitive values like the private_key field which you will not find in the .tfstate file.

Validating the Import

After importing resources, it’s crucial to validate that the imported state matches the actual resource configuration. Use the terraform plan command to review the changes and ensure there are no discrepancies.

1terraform plan

Best Practices for Terraform Imports

  • Backup Your State: Always backup your current Terraform state before performing imports to prevent accidental data loss.
  • Use Descriptive Names: Name your resources descriptively in Terraform to easily identify and manage them.
  • Review and Test: Thoroughly review and test the imported configurations to ensure they function as expected.

Discovering How to Build Terraform Provider Imports

Building imports for a Terraform provider involves defining the logic that allows Terraform to integrate existing resources into its state management. This process ensures that your Terraform configuration can recognize and manage resources that were created outside of Terraform. In this section, we'll introduce you to the essential function required to build Terraform provider imports, using the Mondoo Terraform Provider as an example.

Mondoo uses the terraform-plugin-codegen-framework allowing for an easy and consistent expansion of their Terraform Provider. The Import function of Terraform builds on the standard Terraform Resource created using the plugin framework. It simply adds another function called ImportState, to the existing Metadata, Schema, Create, Read, Update, and Delete functions. We already discussed the necessary building blocks for a Terraform Resource in the first part of this series and will therefore not revisit them.

ImportState Function

 1func (r *TestResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
 2    testPayload, err := r.client.GetTest(ctx, req.ID)
 3    if err != nil {
 4        resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to retrieve test, got error: %s", err))
 5        return
 6    }
 7
 8    model := testResourceResourceModel {
 9        Id:  types.StringValue(testPayload.Id),
10    }
11
12    resp.State.Set(ctx, &model)
13}

The ImportState function reads the existing resource's state and maps it to the Terraform resource schema. This function is crucial for the import process as it ensures that the resource state is accurately reflected in Terraform. In the case of this test implementation we are calling a fictional function called GetTest which in the case of Mondoo would use the GraphQL API to request the resource. We than save the returned data to our Terraform State using resp.State.Set(ctx, &model).

Conclusion

Terraform's import is a powerful feature that facilitates the management of existing infrastructure within Terraform. By leveraging this capability, you can unify your infrastructure management, maintain consistency, and enhance security compliance with Mondoo and Terraform. In this blog post, we’ve explored the importance of Terraform imports, provided a step-by-step guide for importing resources, and shared best practices to ensure a smooth import process.

Be sure to check out our last blog post of this blog series about Mondoo's extended capabilities, where we will discover Mondoo's custom resources using Terraform. Stay tuned to learn more about harnessing the full potential of Mondoo and Terraform for robust infrastructure security and compliance.

Go Back explore our courses

We are here for you

You are interested in our courses or you simply have a question that needs answering? You can contact us at anytime! We will do our best to answer all your questions.

Contact us