Repository: getmoto/moto (python)

Issue:
Organizations `create_account()` should create an IAM role in the new "account"
Hello! Long time, first time. Thanks for the library -- it's hugely useful. I have a (hopefully) small enhancement request.

In AWS Organizations, calling the `organizations:CreateAccount` API results in an IAM role named `OrganizationAccountAccessRole` being created in the new account. The name of the role can be customized using the `RoleName` parameter ([boto3 `Organizations.Client.create_account()` docs](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/organizations/client/create_account.html)).

I would like to propose mirroring that behavior in moto. I could probably sort out how to implement this, but first I wanted to open an issue to see if it's philosophically in line with moto; I don't know if there's any precedent for cross-service interaction like this.

Here are a couple of tests that illustrate the desired behavior:

```python
import os

import boto3
from moto import mock_aws


@mock_aws
def test_create_account_creates_role():
    orgs_client = boto3.client('organizations', region_name='us-west-2')
    _ = orgs_client.create_organization()
    account = orgs_client.create_account(
        AccountName='test_account',
        Email='test@test.xyz',
    )
    account_id = account['CreateAccountStatus']['AccountId']

    os.environ['MOTO_ACCOUNT_ID'] = account_id
    iam_client = boto3.client('iam')
    org_role = iam_client.get_role(RoleName='OrganizationAccountAccessRole')
    assert org_role


@mock_aws
def test_create_account_creates_custom_role():
    orgs_client = boto3.client('organizations', region_name='us-west-2')
    _ = orgs_client.create_organization()
    account = orgs_client.create_account(
        AccountName='test_account',
        Email='test@test.xyz',
        RoleName='CustomOrganizationRole',
    )
    account_id = account['CreateAccountStatus']['AccountId']

    os.environ['MOTO_ACCOUNT_ID'] = account_id
    iam_client = boto3.client('iam')
    org_role = iam_client.get_role(RoleName='CustomOrganizationRole')
    assert org_role
```

Both tests result in an exception on the `get_role()` calls: `botocore.errorfactory.NoSuchEntityException: An error occurred (NoSuchEntity) when calling the GetRole operation: Role CustomOrganizationRole not found`

Pull request:
Organizations: create_account() now comes preconfigured with an IAM role
Fixes #7962 

Patch:
diff --git a/moto/organizations/models.py b/moto/organizations/models.py
index eacdcdee6..2f0f03b18 100644
--- a/moto/organizations/models.py
+++ b/moto/organizations/models.py
@@ -88,6 +88,35 @@ class FakeAccount(BaseModel):
         self.attached_policies: List[FakePolicy] = []
         self.tags = {tag["Key"]: tag["Value"] for tag in kwargs.get("Tags", [])}
 
+        role_name = kwargs.get("RoleName", "OrganizationAccountAccessRole")
+
+        from moto.iam import iam_backends
+        from moto.iam.exceptions import EntityAlreadyExists
+
+        trust_policy = {
+            "Version": "2012-10-17",
+            "Statement": [
+                {
+                    "Effect": "Allow",
+                    "Principal": {"AWS": f"arn:aws:iam::{self.master_account_id}:root"},
+                    "Action": "sts:AssumeRole",
+                }
+            ],
+        }
+        iam = iam_backends[self.id]["global"]
+        try:
+            iam.create_role(
+                role_name=role_name,
+                assume_role_policy_document=json.dumps(trust_policy),
+                path="",
+                permissions_boundary=None,
+                description="",
+                tags=[],
+                max_session_duration="3600",
+            )
+        except EntityAlreadyExists:
+            pass
+
     @property
     def arn(self) -> str:
         partition = get_partition(self.region)


Test patch:
diff --git a/tests/test_organizations/test_organizations_boto3.py b/tests/test_organizations/test_organizations_boto3.py
index 9fa3d567d..5c1ee7d18 100644
--- a/tests/test_organizations/test_organizations_boto3.py
+++ b/tests/test_organizations/test_organizations_boto3.py
@@ -1,12 +1,14 @@
 import json
+import os
 import re
 from datetime import datetime
+from unittest import SkipTest, mock
 
 import boto3
 import pytest
 from botocore.exceptions import ClientError
 
-from moto import mock_aws
+from moto import mock_aws, settings
 from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
 from moto.organizations import utils
 from moto.organizations.exceptions import InvalidInputException, TargetNotFoundException
@@ -75,6 +77,39 @@ def test_create_organization_without_feature_set():
     assert response["Organization"]["FeatureSet"] == "ALL"
 
 
+@mock_aws
+def test_create_account_creates_role():
+    if not settings.TEST_DECORATOR_MODE:
+        raise SkipTest("Involves changing account using env variable")
+    orgs_client = boto3.client("organizations", region_name="us-west-2")
+    orgs_client.create_organization()
+    account = orgs_client.create_account(AccountName="test", Email="test@test.xyz")
+    account_id = account["CreateAccountStatus"]["AccountId"]
+
+    with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account_id}):
+        iam_client = boto3.client("iam", "us-east-1")
+        iam_client.get_role(RoleName="OrganizationAccountAccessRole")
+
+
+@mock_aws
+def test_create_account_creates_custom_role():
+    if not settings.TEST_DECORATOR_MODE:
+        raise SkipTest("Involves changing account using env variable")
+
+    orgs_client = boto3.client("organizations", region_name="us-west-2")
+    _ = orgs_client.create_organization()
+    account = orgs_client.create_account(
+        AccountName="test_account",
+        Email="test@test.xyz",
+        RoleName="CustomOrganizationRole",
+    )
+    account_id = account["CreateAccountStatus"]["AccountId"]
+
+    with mock.patch.dict(os.environ, {"MOTO_ACCOUNT_ID": account_id}):
+        iam_client = boto3.client("iam", "us-east-1")
+        iam_client.get_role(RoleName="CustomOrganizationRole")
+
+
 @mock_aws
 def test_describe_organization():
     client = boto3.client("organizations", region_name="us-east-1")