> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Aws organizations in use remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To remediate “AWS Organizations Should Be Used” for an account where you’re using Route 53, you essentially need to:

        1. put the account into an AWS Organization, and
        2. (optionally) centralize Route 53 management using that Organization.

        Below are the step‑by‑step AWS Console instructions.

        ***

        ## 1. Create or join an AWS Organization

        ### A. If you don’t have an Organization yet

        1. Sign in to the AWS Management Console using the account that will be the management (formerly “master”) account, with `root` or equivalent admin permissions.
        2. Go to **AWS Organizations**:\
           Services → type **“Organizations”** → **AWS Organizations**.
        3. On the **Get started** page, choose **Create an organization**.
        4. Select **Enable all features** (recommended for SCPs and advanced controls) and confirm.

        Your current account is now the **management account** and is part of an Organization.

        ### B. If you already have an Organization and this is a standalone account

        You must invite the standalone account into the existing Organization:

        1. Sign in to the **management account**.
        2. Open **AWS Organizations** → **Accounts** → **Add an AWS account** → **Invite an existing AWS account**.
        3. Enter the **Account ID** and email of the standalone account; send the invitation.
        4. Sign into the **invited account**, open **AWS Organizations**, and under **Invitations**, **Accept** the invitation.

        Once accepted, the account is now a **member account** in the Organization.

        ***

        ## 2. Ensure sharing within the Organization (for central Route 53 use)

        This step helps centralize Route 53 (for example, sharing private hosted zones or related resources across accounts).

        ### A. Enable AWS Resource Access Manager (RAM) sharing with AWS Organizations

        1. In the **management account**, go to **AWS RAM** console.
        2. In the left menu, choose **Settings**.
        3. Under **Resource sharing settings**, enable **Enable sharing with AWS Organizations**.
        4. Save changes.

        ***

        ## 3. (Optional) Centralize Route 53 DNS using the Organization

        If your intent is to manage DNS centrally in one “DNS account” for all Org accounts:

        1. Choose/assign a **central DNS account** in the Organization.
        2. In that DNS account, create the necessary **hosted zones** in Route 53:
           * Go to **Route 53** → **Hosted zones** → **Create hosted zone**.
        3. To share **private hosted zones** with other Org accounts:
           * Go to **Route 53** → **Hosted zones** → select the private hosted zone.
           * Choose **Share hosted zone** (this opens AWS RAM).
           * In AWS RAM, choose **Principals type: AWS Organization** (or specific OUs/accounts).
           * Complete and **Create resource share**.

        Member accounts can now use the shared hosted zone without hosting their own, satisfying centralized management expectations often behind this control.

        ***

        Once the account is part of an AWS Organization, most security/compliance checks for “AWS Organizations should be used” related to Route 53 will pass, assuming the account is correctly recognized as a member of an Organization.
      </Accordion>

      <Accordion title="Using CLI">
        This finding isn’t actually specific to Route 53.\
        “**AWS Organizations Should Be Used**” is an account/organization-level requirement, not a Route 53 configuration. You remediate it by enabling and configuring AWS Organizations for the account that owns your Route 53 resources.

        Below are the step‑by‑step AWS CLI instructions.

        ***

        ### 1. Check if AWS Organizations is already in use

        ```bash theme={null}
        aws organizations describe-organization
        ```

        * If this returns details (with an `Id` like `o-xxxxxxx`), your account is already in an organization.
        * If you get `AWSOrganizationsNotInUseException`, you must create an organization.

        ***

        ### 2. Create an organization (if not already in one)

        Run this from the account you want as the **management (root) account**:

        ```bash theme={null}
        aws organizations create-organization --feature-set ALL
        ```

        * `ALL` enables full features (recommended for governance, SCPs, etc.).

        Verify:

        ```bash theme={null}
        aws organizations describe-organization
        ```

        ***

        ### 3. (Optional) Create Organizational Units (OUs)

        If you want to logically group accounts (e.g., prod / dev):

        1. Get the Root ID:

        ```bash theme={null}
        aws organizations list-roots
        ```

        Note the `"Id"` (e.g., `r-abcd`).

        2. Create an OU under that root:

        ```bash theme={null}
        ROOT_ID="r-abcd"         # replace with your actual root Id
        OU_NAME="Prod"           # example

        aws organizations create-organizational-unit \
          --parent-id "$ROOT_ID" \
          --name "$OU_NAME"
        ```

        Capture the `"Id"` of the new OU from the response if you plan to move accounts into it.

        ***

        ### 4. Invite existing standalone accounts to the organization

        From the **management account**, invite accounts that own Route 53 resources (or any others):

        ```bash theme={null}
        TARGET_EMAIL_OR_ID="123456789012" # can be account ID or email

        aws organizations invite-account-to-organization \
          --target Id="$TARGET_EMAIL_OR_ID",Type="ACCOUNT"
        ```

        The target account must accept the invitation.

        ***

        ### 5. Accept the invitation from the target account

        Log in (or configure AWS CLI credentials) as the target/member account and list invitations:

        ```bash theme={null}
        aws organizations list-handshakes-for-account --filter FilterType=INVITATION
        ```

        Find the `"Id"` of the pending invitation (e.g., `h-abc123xyz`), then:

        ```bash theme={null}
        HANDSHAKE_ID="h-abc123xyz"  # replace with your actual handshake Id

        aws organizations accept-handshake --handshake-id "$HANDSHAKE_ID"
        ```

        Now that account is in your organization.

        ***

        ### 6. (Optional) Move the member account into an OU

        From the **management account**:

        1. Get the account’s Org ID:

        ```bash theme={null}
        aws organizations list-accounts
        ```

        Find the `"Id"` (e.g., `123456789012`) of the account to move.

        2. Get current parent and destination OU:

        ```bash theme={null}
        aws organizations list-parents --child-id 123456789012
        ```

        Note the current `"Id"` as `SOURCE_PARENT_ID` (often the root id).

        Set destination OU id:

        ```bash theme={null}
        DEST_OU_ID="ou-abcd-efghijkl"  # from step 3
        ```

        3. Move:

        ```bash theme={null}
        aws organizations move-account \
          --account-id 123456789012 \
          --source-parent-id "$SOURCE_PARENT_ID" \
          --destination-parent-id "$DEST_OU_ID"
        ```

        ***

        ### 7. (Optional) Attach Service Control Policies (SCPs)

        To enforce governance that might be related to Route 53 usage (e.g., restricting changes to specific accounts):

        1. Create an SCP document `scp-route53-guardrails.json`:

        ```json theme={null}
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "AllowAllByDefault",
              "Effect": "Allow",
              "Action": "*",
              "Resource": "*"
            }
          ]
        }
        ```

        2. Create the policy:

        ```bash theme={null}
        aws organizations create-policy \
          --name "Route53Guardrails" \
          --description "Base SCP (modify to restrict Route 53 if needed)" \
          --type SERVICE_CONTROL_POLICY \
          --content file://scp-route53-guardrails.json
        ```

        3. Attach the SCP to an OU or account:

        ```bash theme={null}
        POLICY_ID="p-abc123xyz"         # from create-policy
        TARGET_ID="ou-abcd-efghijkl"    # OU or account ID

        aws organizations attach-policy \
          --policy-id "$POLICY_ID" \
          --target-id "$TARGET_ID"
        ```

        ***

        Once your account is part of an AWS Organization (with `feature-set` set to `ALL`), the “AWS Organizations Should Be Used” requirement is satisfied for that account and all services it hosts, including Route 53. There is no separate Route 53–specific switch for this control.
      </Accordion>

      <Accordion title="Using Python">
        Below are concise, step‑by‑step instructions to remediate the “AWS Organizations Should Be Used” finding using Python (boto3), with Route 53 in mind.

        **Goal**\
        Ensure the AWS account(s) using Route 53 are members of an AWS Organization (ideally a central Org) so that Route 53 and other services are governed centrally (SCPs, tagging policies, consolidated billing, etc.).

        ***

        ## 1. Prerequisites

        1. Use an **account that will be the management account** (formerly master) for the Organization.
        2. Configure credentials for that account (e.g., via `aws configure` or environment variables).
        3. Install boto3:
           ```bash theme={null}
           pip install boto3
           ```

        ***

        ## 2. Check if an Organization Already Exists

        ```python theme={null}
        import boto3
        from botocore.exceptions import ClientError

        org_client = boto3.client("organizations")

        def get_or_create_organization():
            try:
                resp = org_client.describe_organization()
                print("Organization already exists:", resp["Organization"]["Id"])
                return resp["Organization"]
            except ClientError as e:
                if e.response["Error"]["Code"] == "AWSOrganizationsNotInUseException":
                    print("No organization found, creating one...")
                    resp = org_client.create_organization(
                        FeatureSet="ALL"   # or "CONSOLIDATED_BILLING" if you only want billing
                    )
                    print("Created organization:", resp["Organization"]["Id"])
                    return resp["Organization"]
                else:
                    raise

        if __name__ == "__main__":
            org = get_or_create_organization()
        ```

        Result:\
        You now have an AWS Organization and a **management account**. All Route 53 configuration in this account is now under an Organization.

        ***

        ## 3. Invite Existing Route 53 Accounts into the Organization

        If you have other standalone AWS accounts that host Route 53 hosted zones or records, invite them into this Organization.

        ### 3.1 Send Invitations

        ```python theme={null}
        def invite_account(account_id, email=None, notes=None):
            params = {
                "Target": {
                    "Type": "ACCOUNT",
                    "Id": account_id
                }
            }
            if notes:
                params["Notes"] = notes

            resp = org_client.invite_account_to_organization(**params)
            handshake_id = resp["Handshake"]["Id"]
            print(f"Invitation sent to account {account_id}, handshake: {handshake_id}")
            return handshake_id

        # Example usage:
        if __name__ == "__main__":
            # Replace with the AWS Account IDs where Route53 is configured
            route53_account_ids = ["111111111111", "222222222222"]
            for acc in route53_account_ids:
                invite_account(acc, notes="Join central org for Route53 governance")
        ```

        The invite is sent to the target account. The invitation must be **accepted from the target account** (via console or API).

        ### 3.2 Accept Invitations from Member Accounts (Python Script Per Account)

        From each invited account, configure credentials for that account and run:

        ```python theme={null}
        import boto3

        org_client = boto3.client("organizations")

        def accept_pending_invites():
            resp = org_client.list_handshakes_for_account(Filter={"ActionType": "INVITE"})
            for hs in resp.get("Handshakes", []):
                if hs["State"] == "OPEN":
                    org_client.accept_handshake(HandshakeId=hs["Id"])
                    print("Accepted handshake:", hs["Id"])

        if __name__ == "__main__":
            accept_pending_invites()
        ```

        Result:\
        All your Route 53–using accounts are now **member accounts** in the Organization.

        ***

        ## 4. (Optional but Recommended) Put Route 53 Accounts into an OU

        Organizational Units (OUs) let you group Route 53 accounts to apply consistent policies.

        ```python theme={null}
        def create_ou(parent_id, name):
            resp = org_client.create_organizational_unit(
                ParentId=parent_id,
                Name=name
            )
            print("Created OU:", resp["OrganizationalUnit"]["Id"])
            return resp["OrganizationalUnit"]["Id"]

        def move_account(account_id, source_parent_id, destination_parent_id):
            org_client.move_account(
                AccountId=account_id,
                SourceParentId=source_parent_id,
                DestinationParentId=destination_parent_id
            )
            print(f"Moved account {account_id} from {source_parent_id} to {destination_parent_id}")

        if __name__ == "__main__":
            # Root is normally like r-xxxx
            root_id = org_client.list_roots()["Roots"][0]["Id"]
            route53_ou_id = create_ou(root_id, "route53-accounts")

            # Example: move each Route 53 account into that OU
            route53_account_ids = ["111111111111", "222222222222"]

            for acc in route53_account_ids:
                parents = org_client.list_parents(ChildId=acc)
                current_parent_id = parents["Parents"][0]["Id"]
                move_account(acc, current_parent_id, route53_ou_id)
        ```

        Now you can target Route 53 accounts with specific Service Control Policies.

        ***

        ## 5. (Optional) Apply Service Control Policies (SCPs) for Route 53 Governance

        Examples:

        * Enforce Route 53 is only used in allowed regions (where applicable).
        * Restrict changes to public hosted zones to designated admin roles.

        ### 5.1 Create an SCP

        ```python theme={null}
        import json

        def create_scp(name, description, policy_doc):
            resp = org_client.create_policy(
                Content=json.dumps(policy_doc),
                Description=description,
                Name=name,
                Type="SERVICE_CONTROL_POLICY"
            )
            print("Created SCP:", resp["Policy"]["PolicySummary"]["Id"])
            return resp["Policy"]["PolicySummary"]["Id"]

        # Example: deny deleting hosted zones unless using a specific IAM role
        policy_document = {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "DenyDeleteHostedZoneExceptAdminRole",
                    "Effect": "Deny",
                    "Action": [
                        "route53:DeleteHostedZone"
                    ],
                    "Resource": "*",
                    "Condition": {
                        "StringNotLike": {
                            "aws:PrincipalArn": "arn:aws:iam::*:role/route53-admin*"
                        }
                    }
                }
            ]
        }

        if __name__ == "__main__":
            scp_id = create_scp(
                name="Route53Protection",
                description="Protect Route53 hosted zones; only admin role can delete",
                policy_doc=policy_document
            )
        ```

        ### 5.2 Attach SCP to OU or Accounts

        ```python theme={null}
        def attach_scp(policy_id, target_id):
            org_client.attach_policy(
                PolicyId=policy_id,
                TargetId=target_id
            )
            print(f"Attached SCP {policy_id} to target {target_id}")

        if __name__ == "__main__":
            route53_ou_id = "<route53-OU-ID>"
            scp_id = "<Route53Protection-SCP-ID>"
            attach_scp(scp_id, route53_ou_id)
        ```

        ***

        ## 6. Validate Remediation

        1. Confirm Organization exists and shows your Route 53 accounts as members:
           ```python theme={null}
           print(org_client.describe_organization())
           ```
        2. In each Route 53 account, try actions that should be restricted by SCP (e.g., delete hosted zone) and confirm they are denied if not using the approved role.
        3. Ensure billing and policy management is centrally visible in the management account.

        This configuration satisfies the “AWS Organizations Should Be Used” requirement for the accounts that host Route 53, and lets you centrally govern Route 53 usage and security.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "aws_organizations_organization" "this" {
          # Creates an AWS Organization for the management account that also owns Route53.
          # WARNING: Enabling AWS Organizations is effectively irreversible without
          # closing the organization and/or moving/deleting member accounts.

          feature_set = "ALL" # Use "ALL" to enable all features, not just consolidated billing
        }
        ```

        Substitute nothing: this must be created in the management (formerly “master”) account that owns your Route53 resources, using the AWS Organizations-enabled credentials.

        This change does not force replacement of existing Route53 resources, but it does create an organization that cannot be trivially undone; destroying this resource in Terraform will not automatically unwind the org and its accounts.

        For verification, `terraform plan` should show something like:

        * `Plan: 1 to add, 0 to change, 0 to destroy.`
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
