Sign Up for ArroWS & Mortar — our Free AWS Management & Governance Newsletter
  • Home /
  • Blog /
  • Automating Contact Updates Across Accounts In Your Organization
Automating Contact Updates Across Accounts In Your Organization

Automating Contact Updates Across Accounts In Your Organization

Table of Contents

Updating AWS account contacts across an Organization means calling the account API from the management account (or a delegated admin) so every member account gets the same primary address and the same Security, Operations, and Billing alternate contacts.

Standardizing contact information across a growing AWS footprint is a critical, yet often overlooked, part of cloud governance. Whether it’s ensuring the billing department receives invoices or making sure security notifications reach your SOC, manual updates are not scalable.

Today, we’re sharing a unified automation approach to manage both Primary and Alternate contacts across an entire AWS Organization using Python and Boto3.

What breaks when account contacts go stale?

Member accounts keep whatever address and email they were opened with. Security notifications go to a former employee. Invoices go to a mailbox nobody watches. AWS will not guess the right person. The management account can set both contact types through the account API, which is what the script does.

Primary contact is the legal address on the account: name, company, address, phone. Alternate contacts are three named roles, and only these three: SECURITY, OPERATIONS, and BILLING. Each alternate contact takes a name, title, email, and phone. The script writes both. It does not create IAM users, and it does not change who can sign in.

Which API calls do the work?

Two calls, both from the management account or a delegated administrator for AWS account management. organizations:ListAccounts pages through the member accounts. account:PutContactInformation writes the primary address. account:PutAlternateContact writes one of SECURITY, OPERATIONS, or BILLING. You call the alternate API once per type, so a full pass is one primary write and three alternate writes per account.

As organizations scale, member accounts often end up with stale or inconsistent contact metadata. This can lead to missed security alerts or operational bottlenecks. AWS provides these APIs so you do not click through Account Settings on every member.

The script on our Cacher Snippets library handles both workflows:

  1. Alternate contacts: Security, Operations, and Billing.
  2. Primary contact: corporate address and identity details.

Full code: https://snippets.cacher.io/snippet/78a7e179bfb70e1be449

How do you run it without touching break-glass accounts?

Follow these steps. The exclusion list is the part that keeps the management account and any break-glass accounts on their own contacts.

1. Configure IAM permissions

The execution environment (your laptop, Lambda, or CloudShell) must be authenticated to the management account or a delegated administrator, with:

  • organizations:ListAccounts
  • account:PutContactInformation
  • account:PutAlternateContact

ListAccounts returns pages of accounts. The script follows the paginator so a new account opened last week is in the run. It does not need permission to assume a role into each member account. The account API is called from the management account against the member account id.

2. Set up your exclusion list

Skip the management account and any break-glass accounts. Those should keep a contact path that does not depend on the same mailbox as everything else.

# Skip/Exclude sensitive accounts
if account_id != '111111111111' and account_id != '222222222222':
    put_contact_information(account_id)

Replace the two example account ids with yours. An account id in that list is left exactly as it is. Every other ACTIVE member account is updated. If you also need to skip a suspended account, add its id to the same condition. The script logs each id it skips and each id it writes.

3. Define your standard metadata

Fill ContactInformation with the primary address you want on every member account: full name, company, address, phone. Fill one AlternateContact payload per type. Security should be the SOC mailbox, operations the on-call mailbox, billing the mailbox that actually receives invoices. Use the same payloads for every account in the run so the Organization does not drift again next quarter.

4. Execution

Run it with Python 3 and Boto3, credentials pointed at the management account. The process will:

  • Paginate ListAccounts until there is no NextToken.
  • Skip ids on the exclusion list.
  • Put the primary contact, then SECURITY, OPERATIONS, and BILLING.
  • Print success or the API error for that account id before moving on.

One account failing does not stop the rest. Re-run after you fix the payload. Put calls replace that contact; they do not append a second address.

What does a successful run change?

Each member account not on the exclusion list ends with one primary address and three alternate contacts. IAM users, permission sets, and billing itself are untouched. The next account you create in the Organization is not covered until the next run, which is why the paginator matters: schedule the script, or new accounts keep the email used at creation.

That is the whole change. AWS can reach the SOC and the billing mailbox on every member account you meant to include, and the break-glass accounts still point somewhere else.

Where this sits in the product

Tags :

Share :

Related Posts