AWS Organizations has fundamentally shifted the paradigm of cloud infrastructure management, evolving from a single-account silo to a complex, multi-tenant ecosystem. In this environment, the aws_organizations_account resource within the Terraform AWS provider serves as the atomic unit of expansion, allowing engineers to programmatically provision member accounts that inherit central governance, billing, and security policies. For DevOps teams and cloud architects, managing these accounts via Infrastructure as Code is not merely a convenience; it is a critical requirement for maintaining consistency, security, and auditability across an organization. This article provides an exhaustive technical analysis of the aws_organizations_account resource, covering its implementation, configuration parameters, module-based abstraction, and the broader organizational context in which it operates.
The Role of AWS Organizations in Multi-Account Strategy
AWS Organizations is the backbone of multi-account AWS management. It enables centralized billing, control access, and the enforcement of policies across all member accounts. Within this framework, Service Control Policies (SCPs) act as guardrails, defining the maximum permissions available to entities within specific Organizational Units (OUs). By managing the entire organizational structure and policy framework through Terraform, the organization's topology and security posture remain in version control. This ensures that changes to account structures, such as creating new environments or onboarding new teams, are reviewed, tested, and applied consistently.
The aws_organizations_account resource is specifically designed to create a member account in the current organization. A critical operational constraint is that account management must be executed from the organization's master account (now referred to as the management account in newer AWS terminology). This centralized control point ensures that no account can be created outside of the defined organizational boundary.
Resource Definition and Core Arguments
The Terraform AWS provider provides the aws_organizations_account resource to facilitate the creation of these member accounts. The resource definition is straightforward but requires careful attention to the mandatory and optional arguments to ensure the account is provisioned with the correct security and access profiles.
The following code block demonstrates the basic structure of the resource:
hcl
resource "aws_organizations_account" "account" {
name = "my_new_account"
email = "[email protected]"
}
Understanding the specific arguments is essential for proper configuration. The following table details the supported arguments for the aws_organizations_account resource:
| Argument | Required/Optional | Description |
|---|---|---|
name |
Required | A friendly name for the member account. |
email |
Required | The email address of the owner to assign to the new member account. This email address must not already be associated with another AWS account. |
iam_user_access_to_billing |
Optional | If set to ALLOW, the new account enables IAM users to access account billing information if they have the required permissions. If set to DENY, then only the root user of the new account can access account billing information. |
role_name |
Optional | The name of an IAM role that Organizations automatically preconfigures in the new member account. This role trusts the master account, allowing users in the master account to assume the role, as permitted by the master account administrator. The role has administrator permissions in the new member account. |
The email argument is particularly significant. AWS requires a unique email address for every account. In automated pipelines, this often requires a strategy for generating unique email addresses, such as using + aliases on a domain (e.g., [email protected]), or integrating with a service that generates disposable addresses. Failure to provide a valid, unique email address will result in a provisioning error.
Critical Warning: Destruction and Account Closure
One of the most dangerous aspects of managing AWS accounts via Terraform is the behavior of the destroy command. It is imperative for any engineer using this resource to understand that deleting the aws_organizations_account Terraform resource will only remove the AWS account from the organization. Terraform will not close the account.
This distinction is vital for financial and security reasons. If an account is removed from the organization but not closed, it becomes a standalone account. It will no longer be subject to the SCPs or billing of the organization, but it will continue to exist and incur charges. Furthermore, if the account contains data or resources, it will not be deleted. Therefore, before destroying an account resource, the account must be prepared to be a standalone account, or manually closed via the AWS Console or CLI. Relying on Terraform to clean up the account is a common pitfall that can lead to orphaned, billable resources and security vulnerabilities.
Practical Implementation: Creating Accounts from Scratch
Setting up a new organization often involves creating several resources in a specific order. Before developing application infrastructure, one must establish the organization, define the Organizational Units, and then create the accounts. Terraform facilitates this dependency management effectively.
A typical scenario involves creating an organization with multiple accounts representing different environments, such as users, staging, and production. This approach allows for environment separation at the AWS account level, providing hard isolation between development and production workloads.
Consider the following example where three accounts are created within a newly defined organization:
```hcl
provider "aws" {
region = "eu-central-1"
}
resource "awsorganizationsorganization" "organization" {
# Empty organization definition to establish the root
}
resource "awsorganizationsaccount" "users" {
name = "acme-corp-users"
email = "[email protected]"
role_name = "Admin"
}
resource "awsorganizationsaccount" "staging" {
name = "acme-corp-staging"
email = "[email protected]"
role_name = "Admin"
}
resource "awsorganizationsaccount" "production" {
name = "acme-corp-production"
email = "[email protected]"
role_name = "Admin"
}
```
In this configuration, the users account is dedicated to user management, while staging and production house application infrastructure. The role_name is set to "Admin" in this specific example, which creates an IAM role with administrator permissions. However, best practices often dictate using the default OrganizationAccountAccessRole or a more restrictive role, depending on the security requirements of the organization. Note that each account requires a different email address, as highlighted in the example.
Advanced Organization Configuration
While the focus is on the account resource, it operates within a broader organizational context. When initializing the aws_organizations_organization resource, several critical parameters determine the capabilities of the accounts that will subsequently be created.
A robust configuration includes enabling specific service access principals and policy types. This ensures that accounts within the organization can interact with AWS security and compliance services.
```hcl
resource "awsorganizationsorganization" "main" {
awsserviceaccess_principals = [
"cloudtrail.amazonaws.com",
"config.amazonaws.com",
"sso.amazonaws.com",
"backup.amazonaws.com",
"guardduty.amazonaws.com"
]
feature_set = "ALL"
enabledpolicytypes = [
"SERVICECONTROLPOLICY",
"TAGPOLICY",
"BACKUPPOLICY",
"AISERVICESOPTOUT_POLICY"
]
}
```
The feature_set parameter, when set to ALL, enables all available organization features, which is typical for new organizations. The enabled_policy_types list specifies which types of policies can be attached to OUs and accounts. SERVICE_CONTROL_POLICY is essential for enforcing security guardrails, while TAG_POLICY ensures consistent resource tagging for cost allocation and management.
Once the organization is established, Organizational Units (OUs) can be created to group accounts logically. For example, OUs can be created for environments (Production, Staging, Development) and workloads (Applications, Data, Security, Shared).
```hcl
resource "awsorganizationsorganizationalunit" "environments" {
foreach = toset(["Production", "Staging", "Development"])
name = each.key
parentid = awsorganizationsorganizationalunit.root.id
}
resource "awsorganizationsorganizationalunit" "workloads" {
foreach = toset(["Applications", "Data", "Security", "Shared"])
name = each.key
parentid = awsorganizationsorganizationalunit.root.id
}
```
Accounts created via aws_organizations_account can then be attached to these OUs, allowing for granular application of SCPs. For instance, an SCP can be applied to the Production OU to deny all access to root credentials or restrict specific AWS services.
Abstraction via Terraform Modules
To simplify the management of accounts and ensure consistency across teams, Terraform modules are often utilized. One such module, tmknom/terraform-aws-organizations-account, provides a standardized way to provision AWS Organization accounts with recommended settings. This module abstracts the resource definition and provides inputs for common configuration choices.
The module provides recommended settings, such as enabling access to billing and using the OrganizationAccountAccessRole. The following code demonstrates the usage of this module in both minimal and complete configurations.
Minimal Configuration:
hcl
module "organizations_account" {
source = "git::https://github.com/tmknom/terraform-aws-organizations-account.git?ref=tags/1.0.0"
name = "example"
email = "[email protected]"
}
Complete Configuration:
hcl
module "organizations_account" {
source = "git::https://github.com/tmknom/terraform-aws-organizations-account.git?ref=tags/1.0.0"
name = "example"
email = "[email protected]"
iam_user_access_to_billing = "DENY"
role_name = "OrganizationAccountAccessRole"
enabled = true
}
The inputs for this module are detailed in the following table:
| Input | Description | Type | Default | Required |
|---|---|---|---|---|
email |
The email address of the owner to assign to the new member account. | string | - | yes |
name |
A friendly name for the member account. | string | - | yes |
enabled |
Set to false to prevent the module from creating anything. | string | true | no |
iam_user_access_to_billing |
If set to ALLOW, the new account enables IAM users to access account billing information. | string | ALLOW | no |
role_name |
The name of an IAM role that Organizations automatically preconfigures in the new member account. | string | OrganizationAccountAccessRole | no |
The module also provides outputs that allow other resources or configurations to reference the created account. These outputs include:
| Output | Description |
|---|---|
organizations_account_arn |
The ARN for this account. |
organizations_account_id |
The AWS account ID. |
organizations_account_name |
The AWS account name. |
Using such modules is particularly useful in large organizations where multiple teams might need to request new accounts. By standardizing the module, the organization ensures that all accounts are created with the correct IAM roles and billing access settings, reducing the risk of misconfiguration.
Data Sources and Related Resources
In addition to the resource, the Terraform AWS provider offers a data source, aws_organizations_account, which provides details about a specific existing Organizations Account. This is useful when you need to reference an account ID or ARN without managing its lifecycle.
hcl
data "aws_organizations_account" "example" {
# Required arguments
# Refer to the Terraform Registry docs for details
}
The aws_organizations_account resource is part of a larger family of resources related to AWS Organizations. Understanding these related resources is crucial for a comprehensive implementation:
aws_organizations_aws_service_access: Manages the service access principals for the organization.aws_organizations_delegated_administrator: Associates an account as a delegated administrator for an AWS service.aws_organizations_organization: Creates the organization itself.aws_organizations_organizational_unit: Creates OUs within the organization.aws_organizations_policy: Creates policies (such as SCPs) for the organization.aws_organizations_policy_attachment: Attaches policies to accounts or OUs.aws_organizations_resource_policy: Manages resource policies for the organization.aws_organizations_tag: Manages tags for the organization.aws_organizations_delegated_administrators: Data source to list delegated administrators.
Provider and Version Requirements
To ensure compatibility and access to the latest features, it is recommended to use recent versions of Terraform and the AWS Provider. The following provider configuration block specifies the required versions:
```hcl
terraform {
requiredversion = ">= 1.0"
requiredproviders {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
```
The AWS Provider version ~> 5.0 includes numerous improvements and fixes for Organizations resources. The provider uses the credentials from the management account to perform the necessary API calls. It is crucial that the IAM user or role executing the Terraform commands has the appropriate permissions to manage AWS Organizations. This typically includes permissions such as organizations:CreateAccount, organizations:InviteAccount, and related actions.
Best Practices and Security Considerations
When implementing aws_organizations_account resources, several best practices should be followed to maintain a secure and manageable infrastructure.
- Unique Email Addresses: Always ensure that the email address provided is unique. Using a pattern like
admin+<environment>@<domain>.comis a common and effective strategy. - Restrict Billing Access: Consider setting
iam_user_access_to_billingtoDENYfor most accounts, unless IAM users specifically need to view billing information. This reduces the attack surface and prevents accidental exposure of sensitive financial data. - Role Naming Conventions: Use consistent and descriptive names for the IAM roles created in member accounts. While
OrganizationAccountAccessRoleis the default, custom roles can be created to align with specific security policies. - SCPs Enforcement: Immediately after creating an account and adding it to an OU, apply appropriate SCPs. This ensures that the account is governed by the organization's security policies from the moment it is provisioned.
- Account Cleanup: Establish a process for closing accounts when they are no longer needed. As mentioned, Terraform destroy does not close accounts. A separate step, possibly using the AWS CLI or a custom script, should be implemented to close the account after it has been removed from the organization and all resources have been deleted.
- State Management: Use a secure, remote state backend for Terraform. Since the state file contains information about your AWS accounts, it must be protected against unauthorized access. Services like S3 with DynamoDB locking are commonly used.
Conclusion
The aws_organizations_account resource is a critical component of automated AWS infrastructure management. By leveraging this resource, organizations can scale their multi-account strategy efficiently, ensuring that every new account is provisioned with the correct settings, IAM roles, and organizational affiliations. The ability to manage these accounts through Terraform brings the benefits of Infrastructure as Code to the organizational level, enabling version control, peer review, and consistent deployment.
However, the power of this resource comes with responsibilities. Engineers must be acutely aware of the implications of destroying resources, the importance of unique email addresses, and the need for robust SCPs to govern account behavior. By combining the aws_organizations_account resource with well-structured OUs, comprehensive SCPs, and standardized modules, organizations can build a secure, scalable, and manageable AWS environment. As AWS continues to evolve its Organizations services, the Terraform provider will likely introduce new features and enhancements, further simplifying the management of complex multi-account landscapes. Staying current with provider updates and best practices is essential for maximizing the value of this powerful resource.