🐶
Terraform

Terraform Apply with AWS Assume Role: A Complete Guide

By Filip on 10/07/2024

Learn how to leverage AWS assume role capabilities for seamless and secure Terraform deployments in your cloud infrastructure.

Terraform Apply with AWS Assume Role: A Complete Guide

Table of Contents

Introduction

Managing infrastructure across multiple AWS accounts is a common scenario in cloud environments. Terraform, a popular Infrastructure as Code (IaC) tool, provides a mechanism to interact with and manage resources in AWS accounts you don't directly control. This approach leverages AWS's AssumeRole functionality to enhance security and streamline cross-account resource management.

Step-by-Step Guide

To use Terraform to manage resources in an AWS account you don't directly control (like a different AWS account), you can leverage AWS's AssumeRole functionality. Here's how:

  1. Understand AssumeRole: AssumeRole lets an IAM user (or another AWS service) temporarily take on the permissions of a different IAM role. This is perfect for cross-account access in Terraform.

  2. Prerequisites:

    • IAM Role in the Target Account: Create an IAM role in the AWS account where you want to deploy resources. This role should have the necessary permissions for Terraform to operate (e.g., create EC2 instances, S3 buckets, etc.).
    • Trust Policy: Configure the role's trust policy to allow your IAM user (or the service running Terraform) to assume this role.
  3. Terraform Configuration:

    • Provider Configuration: In your Terraform code, configure the AWS provider to use AssumeRole:
      provider "aws" {
        region = "your-target-region"
        assume_role {
          role_arn = "arn:aws:iam::TARGET_ACCOUNT_ID:role/YOUR_ROLE_NAME"
          session_name = "TerraformSession" # Optional, for session naming
        }
      }
      • Replace TARGET_ACCOUNT_ID and YOUR_ROLE_NAME with the actual values.
  4. Authentication:

    • AWS CLI Credentials: Ensure your local AWS CLI is configured with credentials that have permission to assume the role you defined in your Terraform code. This is usually your regular IAM user.
    • Terraform Execution: When you run Terraform commands (e.g., terraform apply), the AWS provider will automatically use your local AWS credentials to assume the specified role. This grants Terraform the permissions it needs in the target account.
  5. Important Considerations:

    • Security: Carefully manage the permissions granted to the IAM role being assumed. Follow the principle of least privilege.
    • Session Duration: AssumeRole sessions have time limits (default is 1 hour). If your Terraform operations take longer, you might need to configure longer session durations or use alternative approaches.
    • Terraform Cloud/Enterprise: If you're using Terraform Cloud or Enterprise, you'll need to configure environment variables within your workspace to store the necessary AWS credentials securely.

By following these steps, you can effectively use Terraform to manage resources across different AWS accounts using AssumeRole, enhancing security and simplifying your infrastructure management.

Code Example

This code demonstrates how to create an S3 bucket in a different AWS account (Account B) from your main account (Account A) using Terraform's AssumeRole functionality. In Account B, you create an IAM role with permissions to create S3 buckets and allow your IAM user from Account A to assume this role. In Account A, your Terraform code uses the 'assume_role' block within the AWS provider to specify the role ARN from Account B. When you run 'terraform apply', Terraform uses your local AWS credentials to obtain temporary credentials for the role in Account B, allowing it to create the S3 bucket in the target account. This setup ensures secure cross-account resource provisioning in AWS.

This example demonstrates how to use Terraform to create an S3 bucket in a different AWS account using AssumeRole.

Target Account (Account B):

  1. Create an IAM Role:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::YOUR_ACCOUNT_ID:user/YOUR_IAM_USER" 
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
    • Replace YOUR_ACCOUNT_ID and YOUR_IAM_USER with the account ID and IAM user from your main account (Account A).
    • Attach a policy to this role with permissions to create S3 buckets (e.g., AmazonS3FullAccess).

Main Account (Account A):

  1. Terraform Configuration (main.tf):

    terraform {
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = "~> 4.0"
        }
      }
    }
    
    provider "aws" {
      region = "us-west-2" # Replace with your target region
      assume_role {
        role_arn = "arn:aws:iam::TARGET_ACCOUNT_ID:role/YOUR_ROLE_NAME"
      }
    }
    
    resource "aws_s3_bucket" "example" {
      bucket = "my-bucket-in-another-account"
      acl    = "private"
    
      tags = {
        Name = "Example bucket created with Terraform and AssumeRole"
      }
    }
    • Replace TARGET_ACCOUNT_ID and YOUR_ROLE_NAME with the values from Account B.
  2. Authentication:

    • Make sure your local AWS CLI is configured with credentials for your IAM user in Account A (the user allowed to assume the role).
  3. Deploy:

    • Run terraform init to initialize the project.
    • Run terraform apply to create the S3 bucket in Account B.

Explanation:

  • The assume_role block in the aws provider tells Terraform to assume the specified role in Account B.
  • When you run terraform apply, Terraform uses your local AWS credentials to get temporary credentials for the role in Account B.
  • With these temporary credentials, Terraform can then create the S3 bucket in the target account.

Important:

  • This is a basic example. In a real-world scenario, you'd likely use more sophisticated IAM policies and potentially modules for better organization.
  • Always follow security best practices and grant the least privilege necessary to the IAM role being assumed.

Additional Notes

Best Practices:

  • Principle of Least Privilege: Always grant the absolute minimum permissions to the IAM role in the target account that Terraform needs to perform its tasks. This minimizes potential damage if the role's credentials are compromised.
  • Separate Roles for Different Environments: Consider using different IAM roles for different environments (development, staging, production) to further isolate permissions.
  • Externalize Sensitive Information: Never hardcode AWS credentials or secrets directly in your Terraform code. Use environment variables, configuration files, or secret management solutions like AWS Secrets Manager.
  • Regularly Review and Rotate Credentials: Periodically review the permissions granted to the IAM roles and rotate credentials to enhance security.

Troubleshooting:

  • Access Denied Errors: The most common issue is encountering "AccessDenied" errors. Double-check the following:
    • The IAM role in the target account exists and has the correct permissions.
    • The trust policy of the role allows your IAM user or the service running Terraform to assume the role.
    • Your local AWS credentials have permission to assume the role.
  • Session Timeout: If your Terraform operations consistently timeout, you might need to increase the session duration for the assumed role. Be mindful of the security implications of longer session durations.

Alternatives to AssumeRole:

  • AWS Organizations: If you manage multiple AWS accounts within AWS Organizations, you can leverage service control policies (SCPs) to control access to resources across accounts.
  • Terraform Workspaces: Workspaces can help manage different environments or deployments within a single Terraform configuration. However, they don't directly address cross-account access.

Additional Tips:

  • Terraform State: When working with multiple accounts, carefully consider where you store your Terraform state. Using a shared state file can lead to conflicts. Consider using remote state storage like AWS S3 or Terraform Cloud.
  • Documentation: Clearly document the IAM roles, trust policies, and Terraform configurations used for cross-account access to facilitate understanding and maintenance.

Summary

This table summarizes how to use Terraform to manage resources in a different AWS account using AssumeRole:

Step Description Key Points
1. Understand AssumeRole - Allows temporary assumption of another IAM role's permissions.
- Ideal for secure cross-account access in Terraform.
2. Prerequisites Target Account:
- Create an IAM role with necessary permissions for Terraform.
- Configure the role's trust policy to allow your IAM user or service to assume it.
- Define permissions based on the principle of least privilege.
3. Terraform Configuration Provider Configuration:
- Configure the AWS provider to use assume_role.
- Specify the role_arn and optionally a session_name.
- Replace placeholders with actual account ID and role name.
4. Authentication - Ensure your local AWS CLI has credentials with permission to assume the defined role. - Terraform will automatically use these credentials to assume the role during execution.
5. Important Considerations - Security: Carefully manage the assumed role's permissions.
- Session Duration: Handle potential timeouts for long-running operations.
- Terraform Cloud/Enterprise: Securely configure environment variables for credentials.
- Prioritize security and plan for session management.

By following these steps, you can leverage AssumeRole for secure and streamlined cross-account resource management with Terraform.

Conclusion

In conclusion, managing infrastructure across multiple AWS accounts is made significantly easier and more secure with Terraform's AssumeRole functionality. By configuring an IAM role in the target account and utilizing the assume_role block within your Terraform code, you can seamlessly provision resources without needing to directly manage credentials for the target account. This approach, combined with security best practices like the principle of least privilege and proper credential management, empowers organizations to maintain a secure and efficient multi-account AWS environment. As your infrastructure grows, mastering Terraform's AssumeRole capabilities will prove invaluable for managing complex deployments and ensuring secure cross-account access within your AWS ecosystem.

References

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait