|
#!/usr/bin/env bash |
|
|
|
# |
|
# create-account.sh |
|
# - create and optionally close an AWS Organizations account in one flow. |
|
# - This is to demonstrate steps and permissions needed to create an AWS account |
|
# - must be run from the AWS Org management account. |
|
# |
|
|
|
## Configuration |
|
# |
|
# Edit the global variables at the top of the script before running: |
|
# |
|
# | Variable | Description | |
|
# |----------|-------------| |
|
# | DEST_OU | The target OU ID where the new account will be moved | |
|
# | BASE_NAME | Prefix used for the account name and email | |
|
# | E_DOMAIN | Email domain for the account's root email address | |
|
# |
|
# A random number is appended to `BASE_NAME` to ensure unique account names and emails on each run. |
|
# |
|
|
|
## What it does |
|
# |
|
# 1. Creates a new AWS account under the organization using a generated name and email |
|
# 2. Polls until account creation succeeds or fails |
|
# 3. Creates a local AWS CLI profile for the new account using `OrganizationAccountAccessRole` |
|
# 4. Moves the account to the configured destination OU |
|
# 5. Waits 30 seconds, then closes the account unless cancelled |
|
# |
|
|
|
# |
|
# Set Global Variables |
|
# |
|
|
|
# modify these: |
|
DEST_OU=ou-tbjl-c9ih5yjt ## The OU where you want the new account |
|
BASE_NAME=user1 ## this should be a real email user |
|
E_DOMAIN=example.com ## a real email domain |
|
|
|
|
|
# Generate account name and email |
|
RAND=$RANDOM |
|
EMAIL=${BASE_NAME}+${RAND}@${E_DOMAIN} |
|
ACCOUNT_NAME=${BASE_NAME}-${RAND} |
|
|
|
# our org root id |
|
ROOT_ID=$(aws organizations list-roots --query 'Roots[0].Id' --output text) |
|
|
|
|
|
# |
|
# Create new account |
|
# |
|
REQUEST_ID=$(aws organizations create-account \ |
|
--email "$EMAIL" \ |
|
--account-name "$ACCOUNT_NAME" \ |
|
--query 'CreateAccountStatus.Id' \ |
|
--output text) |
|
|
|
echo "Request ID: $REQUEST_ID" |
|
|
|
while true; do |
|
STATE=$(aws organizations describe-create-account-status \ |
|
--create-account-request-id "$REQUEST_ID" \ |
|
--query 'CreateAccountStatus.State' \ |
|
--output text) |
|
echo "State: $STATE" |
|
|
|
if [ "$STATE" = "SUCCEEDED" ]; then |
|
NEW_ACCOUNT_ID=$(aws organizations describe-create-account-status \ |
|
--create-account-request-id "$REQUEST_ID" \ |
|
--query 'CreateAccountStatus.AccountId' \ |
|
--output text) |
|
echo "New account ID: $NEW_ACCOUNT_ID" |
|
break |
|
|
|
elif [ "$STATE" = "FAILED" ]; then |
|
FAILURE=$(aws organizations describe-create-account-status \ |
|
--create-account-request-id "$REQUEST_ID" \ |
|
--query 'CreateAccountStatus.FailureReason' \ |
|
--output text) |
|
echo "Failed: $FAILURE" |
|
exit 1 |
|
fi |
|
sleep 10 |
|
done |
|
|
|
echo "New account $ACCOUNT_NAME $NEW_ACCOUNT_ID created" |
|
|
|
# |
|
# create profile for the new account to assume a role for testing and configuration |
|
# |
|
|
|
echo "Creating profile $ACCOUNT_NAME for account $NEW_ACCOUNT_ID" |
|
|
|
aws configure set role_arn arn:aws:iam::$NEW_ACCOUNT_ID:role/OrganizationAccountAccessRole --profile $ACCOUNT_NAME |
|
aws configure set source_profile default --profile $ACCOUNT_NAME |
|
|
|
# |
|
# Using the new profile, you can run any needed setup/gurdrails in the new account |
|
# |
|
|
|
# sample command in the new account |
|
aws sts get-caller-identity --profile $ACCOUNT_NAME |
|
|
|
# |
|
# Move account to desired OU |
|
# |
|
|
|
aws organizations move-account --account-id $NEW_ACCOUNT_ID --source-parent-id $ROOT_ID --destination-parent-id $DEST_OU |
|
|
|
# confirm org moved |
|
aws organizations list-parents --child-id $NEW_ACCOUNT_ID --query 'Parents[0].Id' --output text |
|
|
|
echo "Account $ACCOUNT_NAME moved to OU $DEST_OU" |
|
|
|
|
|
# |
|
# Close account |
|
# |
|
|
|
CLOSE_TIMEOUT=30 |
|
echo "Account will be closed in $CLOSE_TIMEOUT seconds. Press any key to cancel..." |
|
if ! read -t $CLOSE_TIMEOUT -n 1; then |
|
echo -e "\nProceeding with account closure..." |
|
|
|
aws organizations close-account --account-id $NEW_ACCOUNT_ID |
|
|
|
# confirm State is "CLOSED" |
|
FINAL_STATE=$(aws organizations describe-account --account-id $NEW_ACCOUNT_ID --query 'Account.State' --output text) |
|
echo "The state of account $NEW_ACCOUNT_ID is now $FINAL_STATE" |
|
|
|
else |
|
echo -e "\nCancelled." |
|
fi |