How To Manage IAM Access Analyzer in AWS Organizations Using Terraform

Anthony Wat - May 27 - - Dev Community

Introduction

Since I began covering the implementation of security controls in AWS, I have provided walkthroughs on configuring Amazon GuardDuty and AWS Security Hub in a centralized setup using Terraform. In this blog post, we will explore another security service: AWS IAM Access Analyzer. This service helps identify unintended external access or unused access within your organization. Setting up IAM Access Analyzer is simpler than the other services, so let's dive right in!

About the use case

AWS Identity and Access Management (IAM) Access Analyzer is a feature of AWS IAM that identifies resources shared with external entities and detects unused access, enabling you to mitigate any unintended or obsolete permissions.

IAM Access Analyzer can be used in AWS Organizations, allowing analyzers that use the organization as the zone of trust to be managed by either the management account or a delegated administrator account. This enables the consolidation of findings, which can then be ingested by AWS Security Hub in a centralized setup.

Since it is increasingly common to establish an AWS landing zone using AWS Control Tower, we will use the standard account structure in a Control Tower landing zone to demonstrate how to configure IAM Access Analyzer in Terraform:

Control Tower standard OU and account structure

The relevant accounts for our use case in the landing zone are:

  1. The Management account for the organization where AWS Organizations is configured. For details, refer to Settings for IAM Access Analyzer.

  2. The Audit account where security and compliance services are typically centralized in a Control Tower landing zone.

The objective is to delegate IAM Access Analyzer administrative duties from the Management account to the Audit account, after which all organization configurations are managed in the Audit account. With that said, let's see how we can achieve this using Terraform!

Designating an IAM Access Analyzer administrator account

The IAM Access Analyzer delegated administrator is configured in the Management account, so we need a provider associated with it in Terraform. To simplify the setup, we will use a multi-provider approach by defining two providers: one for the Management account and another for the Audit account. We will use AWS CLI profiles as follows:

provider "aws" {
  alias   = "management"
  # Use "aws configure" to create the "management" profile with the Management account credentials
  profile = "management" 
}

provider "aws" {
  alias   = "audit"
  # Use "aws configure" to create the "audit" profile with the Audit account credentials
  profile = "audit" 
}
Enter fullscreen mode Exit fullscreen mode

Unlike other security services that have specific Terraform resources for designating a delegated administrator, this is done using the more general aws_organizations_delegated_administrator resource as follows:

data "aws_caller_identity" "audit" {
  provider = aws.audit
}

resource "aws_organizations_delegated_administrator" "this" {
  provider          = aws.management
  account_id        = data.aws_caller_identity.audit.account_id
  service_principal = "access-analyzer.amazonaws.com"
}
Enter fullscreen mode Exit fullscreen mode

With the Audit account designated as the IAM Access Analyzer administrator, we can now create the analyzers for the organization.

Creating analyzers with organizational zone of trust

As mentioned earlier, there are two types of analyzers: external access and unused access. To make the setup more configurable, we will add some variables and keep them in a separate file called variables.tf. To create the external access analyzer with the organization as the zone of trust, we can define the Terraform configuration as follows:

# Defined in variables.tf

variable "org_external_access_analyzer_name" {
  description = "The name of the organization external access analyzer."
  type        = string
  default     = "OrgExternalAccessAnalyzer"
}
Enter fullscreen mode Exit fullscreen mode
# Defined in main.tf

resource "aws_accessanalyzer_analyzer" "org_external_access" {
  provider      = aws.audit
  analyzer_name = var.org_external_access_analyzer_name
  type          = "ORGANIZATION"
  depends_on    = [aws_organizations_delegated_administrator.this]
}
Enter fullscreen mode Exit fullscreen mode

Since the unused access analyzer is a paid feature, we ought to make it optional. The Terraform configuration can be defined in the following manner:

# Defined in variables.tf

variable "org_unused_access_analyzer_name" {
  description = "The name of the organization unused access analyzer."
  type        = string
  default     = "OrgUnusedAccessAnalyzer"
}

variable "eanble_unused_access" {
  description = "Whether organizational unused access analysis should be enabled."
  type        = bool
  default     = false
}

variable "unused_access_age" {
  description = "The specified access age in days for which to generate findings for unused access."
  type        = number
  default     = 90
}
Enter fullscreen mode Exit fullscreen mode
resource "aws_accessanalyzer_analyzer" "org_unused_access" {
  provider      = aws.audit
  count         = var.eanble_unused_access ? 1 : 0
  analyzer_name = var.org_unused_access_analyzer_name
  type          = "ORGANIZATION_UNUSED_ACCESS"
  configuration {
    unused_access {
      unused_access_age = var.unused_access_age
    }
  }
  depends_on = [aws_organizations_delegated_administrator.this]
}
Enter fullscreen mode Exit fullscreen mode

✅ You can find the complete Terraform in the GitHub repository that accompanies this blog post.

With the complete Terraform configuration, you can now apply it with the appropriate variable values to establish the Audit account as the delegated administrator and create the analyzers with the organization as the zone of trust.

Additional considerations

IAM Access Analyzer is a regional service, so you must create an analyzer in each region. However, it primarily applies to external access analysis, which examines the policies of regional resources such as S3 buckets and KMS keys. Since unused access analysis works with IAM users and roles, which are global resources, creating multiple unused access analyzers would only increase costs without adding value. Therefore, it is recommended to create one external access analyzer per region and only one unused access analyzer in the home region.

Another consideration is that there are times when the organizational zone of trust is not desirable. For example, if you wish to have full segregation of member accounts because they represent different tenants, then you would actually want analyzers created in each member account with itself as the zone of trust. This unfortunately would have to be managed at a per-account level.

Summary

In this blog post, you learned how to manage IAM Access Analyzer in AWS Organizations using Terraform by defining a delegated administrator and using analyzers with the organization as the zone of trust. If you have also configured AWS Security Hub to operate at the organization level, you can manage IAM Access Analyzer findings across accounts and regions, thereby streamlining your security operations.

I hope you find this blog post helpful. Be sure to keep an eye out for more how-to articles on configuring other AWS security services in Terraform, or learn about other topics like generative AI, on the Avangards Blog.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .