Import Stack Resource

Importing Stack Resource

In this guide, you'll learn how to:

Guardrails allows you to bring existing AWS resource(s) under stack management using import statements. This enables Guardrails to track and enforce configuration policies on the imported resources.

Prerequisites

[!IMPORTANT] While this guide demonstrates configuring AWS > IAM > Stack [Native] in Enforce mode, it is strongly recommended to start with Check mode first. Check mode allows you to:

Once you've confirmed everything works as intended in Check mode, you can safely switch to Enforce mode.

Step 1: Find Existing Resource

Before importing, identify the AWS IAM role that you want to manage using Guardrails.

Log in to the AWS Console and navigate to the IAM service. Search for the role you want to import. In this example, we'll search for a role named stack-import-demo-role.

Select the IAM role name.

To get the role details using AWS CLI, execute the following command:

aws iam get-role --role-name stack-import-demo-role

Expected CLI output:

{
  "Role": {
    "Path": "/",
    "RoleName": "stack-import-demo-role",
    "RoleId": "AROA2AWXV46KEICE3ITXA",
    "Arn": "arn:aws:iam::688720831234:role/stack-import-demo-role",
    "CreateDate": "2025-04-02T12:20:31+00:00",
    "AssumeRolePolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Service": "ec2.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    },
    "Description": "stack-import-demo-role",
    "MaxSessionDuration": 3600,
    "RoleLastUsed": {}
  }
}

Step 2: Prepare Import Script

We will make use of the Import block to import this existing IAM Role.

Import block:

import {
  to = aws_iam_role.stack_import_demo_role
  id = "stack-import-demo-role"
}

[!NOTE] The identifier you use for a resource's import ID is resource-specific. You can find the required ID in the provider's documentation for the resource you wish to import.

To import the IAM role, update the following policies to import the above resource.

Step 3: Configure AWS > IAM > Stack [Native] > Modifier Policy

  1. Login to Guardrails console and navigate to Policies tab.
  2. Search for AWS > IAM > Stack [Native] > Modifier.
  3. Select New Policy Setting.
  4. Apply the following Terraform import block in the policy at the account level.

Required policy value:

import {
  to = aws_iam_role.stack_import_demo_role
  id = "stack-import-demo-role"
}

!Set AWS > IAM > Stack [Native] > Modifier

  1. Select Save to apply the policy.

Step 4: Configure AWS > IAM > Stack [Native Policy] > Source Policy

Now set the AWS > IAM > Stack [Native] > Source policy with the OpenTofu HCL configuration source code of the resource.

  1. Go to Policies in the Guardrails console.
  2. Search for AWS > IAM > Stack [Native] > Source.
  3. Select New Policy Setting.
  4. Apply the following Terraform import block in the policy at the account level.

Required Terraform configuration:

resource "aws_iam_role" "stack_import_demo_role" {
  name        = "stack-import-demo-role"
  description = "stack-import-demo-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      },
    ]
  })
}

!Set AWS > IAM > Stack [Native] > Source

Select Update to apply the policy.

Step 5 Configure AWS > IAM > Stack [Native] Policy

Now set the AWS > IAM > Stack [Native] policy to enforce mode to import and manage the IAM resource. This ensures Guardrails takes control of the resource's lifecycle management.

  1. Go to Policies in the Guardrails console.
  2. Search for AWS > IAM > Stack [Native] policy.
  3. Click New Policy Setting.
  4. Select "Enforce: Configured"
  5. Select Create to create the policy setting.

!Set AWS > IAM > Stack [Native]

Step 6: Validate the AWS > IAM > Stack [Native] Stack Control

Once the necessary policies are set, the AWS > IAM > Stack [Native] stack will execute and import the resource. If everything goes well, you should see the below log message "Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed."

!Set AWS > IAM > Stack [Native]

View control logs to check the if the stack successfully imported the resource.

!AWS > IAM > Stack [Native] -- Control Logs

Step 7: Manage Stack with Updates

Now that the resource is imported to the Stack. You can manage the resource using the Stack. Try updating the AWS > IAM > Stack [Native] > Source and the changes should reflect in the AWS IAM Role.

Let's update by adding a tag to the IAM role.

  1. Go to AWS > IAM > Stack [Native] > Source in the Guardrails console
  2. Update the source with the following code to add tags to the IAM Role:
resource "aws_iam_role" "stack_import_demo_role" {
  name        = "stack-import-demo-role"
  description = "stack-import-demo-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      },
    ]
  })

  tags = {
    environment = "development"    ### Add the Tags block
  }
}

If everything goes well, you should see the following log message, Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

!AWS > IAM > Stack [Native] -- Control Logs

Importing Multiple Resources

Follow the same process, but instead use for_each to iterate through multiple resources. Here are the policies and required values:

Step 1: Configure AWS > IAM > Stack [Native] > Modifier

import {
  to       = aws_iam_role.demo_roles[each.key]
  id       = each.key
  for_each = var.role_names
}

Step 2: Configure AWS > IAM > Stack [Native] > Source

variable "role_names" {
  description = "List of IAM role names to import"
  type        = set(string)
}

resource "aws_iam_role" "demo_roles" {
  for_each = var.role_names

  name        = each.value
  description = each.value

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      },
    ]
  })
}

Step 3: Configure AWS > IAM > Stack [Native] > Variables

[!TIP]

role_names = [
  "stack-import-demo-roles-1",
  "stack-import-demo-roles-2",
  "stack-import-demo-roles-3"
]

Step 4: Configure AWS > IAM > Stack [Native]

Now enforce the changes, select, Enforce: Configured.

If everything goes well, you should see the following log message, Apply complete! Resources: 3 imported, 0 added, 0 changed, 0 destroyed.

!AWS > IAM > Stack [Native] -- Control Logs

Importing Regional Stack Resources

Similar to the above, regional Stack [Native] controls are used when you need to manage resources that are region-specific in AWS. This is important because:

[!TIP]

Here's how to use Regional Stack [Native] to import region-specific resources using below policies with an example to import a S3 bucket stack-import-demo-bucket

When importing S3 buckets:

Step 1: AWS > Region > Stack [Native] > Modifier

import {
  to = aws_s3_bucket.example
  id = "stack-import-demo-bucket"
}

Step 2: AWS > Region > Stack [Native] > Source

resource "aws_s3_bucket" "example" {
  bucket = "stack-import-demo-bucket"
}

Step 3: AWS > Region > Stack [Native]

To enforce, set the policy to Enforce: Configuredat the region where you want to import the bucket.

[!NOTE] If this bucket exists in all regions and you want to import all such buckets, then set this policy at the account level.

If everything goes well, you should see the following log message, Apply complete! Resources: 3 imported, 0 added, 0 changed, 0 destroyed.

!AWS > Region > Stack [Native] -- Control Logs

Resource Stack [Native]

Resource Stack [Native] controls allow you to manage resources that are associated with a specific parent resource. Resource stacks target individual resources, allowing you to configure standard resources that should be associated with them. Resource stacks will run for every resource of that type, and will run whenever new resources of that type are discovered. More info at Stack [Native] Guardrails concepts.

For example, with S3 buckets:

Let us walk through an example use-case. To add a lifecycle policy for all the S3 buckets within a region/account/folder to delete log files older than a year. This applies to all objects under the logs/ prefix (i.e. logs/filename.log)

Use Case: Delete S3 Logs Older Than One Year

[!NOTE] Please refer to Stack [Native] Best Practices

We will use a calculated policy for the variables.

Step 1: Configure AWS > S3 > Bucket > Stack [Native] > Variables

GraphQL Input Query

{
  resource {
    Name: get(path:"Name")
  }
}

Nunjucks Template

bucket_name = "{{ $.resource.Name  }}"

Step 2: Configure AWS > S3 > Bucket > Stack [Native] > Modifier

import {
  to = aws_s3_bucket.example
  id = var.bucket_name
}

Step 3: Configure WS > S3 > Bucket > Stack [Native] > Source

variable "bucket_name" {
  description = "Name of the bucket"
  type        = string
}

resource "aws_s3_bucket" "example" {
  bucket = var.bucket_name
}

resource "aws_s3_bucket_lifecycle_configuration" "logs" {
  bucket = var.bucket_name

  rule {
    id     = "delete-logs-after-365-days"
    status = "Enabled"

    filter {
      prefix = "logs/"
    }

    expiration {
      days = 365
    }
  }
}

Step 4: Configure AWS > S3 > Bucket > Stack [Native]

To enforce, set the policy to Enforce: Configured at the region/account/folder.

Review

Validate Resource

Next Steps

Troubleshooting

Issue Description Guide
Resource Not Found Import failed due to an incorrect Role name. Verify the Role name in AWS Console.
Permission Denied Guardrails lacks the required permissions. Ensure IAM roles are correctly assigned.
Import Fails in Terraform The resource is already managed. Remove the resource from Terraform state before re-importing.