[toc]
- Ansible >= 2.4
AdministratorAcces
on the Organization account- Environment variables are set and exported:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION
- A configuration file that describes your complete account setup
- A personal configuration file
~/.aws-account-config.yml
that holds variables that might differ from user to user.
This is the main playbook, and it includes all other playbooks
The configuration file looks like this:
### The organization account configured the sub-accounts, and
### has the necessary AssumeRoles permissions to perform all
### required IAM actions on the new accounts. These credentials
### are very valuable, and should only be active when running
### this playbook!!!
organization:
account_id: "123456789012"
name: acme
environments:
- dev
- stg
- prd
- sandbox
entities:
- acme
- acme_emea
bastion_account:
name: acme.bastion
account_id: "012345678901"
console_url: "https://acme-bastion.signin.aws.amazon.com/console"
subaccounts:
- name: acme.sandbox
account_id: "234567890123"
environment: sandbox
- name: acme.salesapp
account_id: "345678901234"
environment: prd
### Groups will be created on the bastion account only.
### Group names are <name>-<accountid>, where <name> is the groupname
### defined in this list, and <account-id> is the account id of the
### subaccounts listed in the subaccounts list.
### Membership to a group implies the permissions to assume the role
### (i.e read) on the account with that account id
aws_groups:
- name: AssumeRead
role: read
- name: AssumePower
role: power
- name: AssumeAdmin
role: admin
### Roles are created on every subaccount, they are required to have users
### assume a role
aws_roles:
- name: read
managed_policies:
- ReadOnlyAccess
- name: admin
managed_policies:
- AdministratorAccess
- name: power
managed_policies:
- PowerUserAccess
### Users
#default_groups: "{{ ['ManageYourOwnUser'] + ( subaccounts | map(attribute='name') | map('regex_replace', '^', 'AssumeRead-') | list ) }}"
#aws_users:
# - name: rtytgat
# groups: "{{ subaccounts | map(attribute='name') | map('regex_replace', '^', 'AssumeAdmin-') | list }}"
default_groups:
- ManageYourOwnUser
aws_users:
- name: "john.doe@acme.com"
groups:
- Admin
accounts_valid:
from: "2021-01-01T00:00:00Z"
until: "2021-06-30T23:59:59Z"
accounts:
- name: ".*prd.*"
role: "readlocal"
- name: ".*sandbox.*"
role: "adminlocal"
- name: "bill.smith@acme.com"
groups:
- AssumeRead-acme.salesapp-prd
Create all Service Accounts on the bastion account.
Create all CodeArtifact deploy users (read-only access) on the bastion account.
These users will have permissions to assume the role arn:aws:iam::123456789012:role/CodeArtifactReadOnly
,
that's a role on the tooling account (where the CodeArtifact repository lives).
The role CodeArtifactReadOnly
on the tooling account is not created by aws-account-config
, make sure
you create it to make things work.
Create all ECR deploy users (read-only access) on the bastion account. This user wil have permissions to assume a role on the tooling account with permissions on a predefined set of ECR repo's only.
- Allow new AWS accounts to access certain resources on the tooling account
- Create roles in the tooling account for fine-grained access to ECR repositories for
ECR deploy users defined in the Bastion account (with the tag
bastion_create_ecr_deploy_users
)
Create the per-user IAM policy granting assumerole permissions for the configured subaccounts to the user, and attaches the policy to the user.
Create the .html
file with all available cross-account links
Create the groups and group policies on the Bastion account
Perform everyting on the Bastion account. This is basically the complete playbook, but without:
html
- Creation of the roles on the subaccounts
Set the IAM password policy on all subaccounts.
Only create users and assign groups to the users. Since users only exist on the Bastion account, this is the only account involved.
Do not run the monitoring
and security
playbooks.
Only run the security
tasks.
Only run the monitoring
tasks.
Only run the playbooks that change stuff on the subaccounts.
If the variable subaccount_limit
is set, the subaccount actions are
only performed for that account.
--extra-vars subaccount_limit=ixor.acertabudgettool-dev
Only run the guardduty
tasks.
The configuration file to use. The configuration file contains the description of your account structure, defines the Organization account, the account to use as the Bastion account, all subaccounts, users and group membership for the users.
Limit the subaccount actions to the specified subaccount
ansible-playbook aws-account-setup.yml \
--extra-vars=config_file=../aws-account-config-ixor/aws-account-config.yml \
--tags=bastion_create_service_accounts,security_subaccount_service_accounts
TODO
This functionality uses the file sa_bb_config.yml
in the BitbucketRepoConfigs
directory of the {{ config_file }}
basedir to populate the repo variables.
The config file looks like this:
repos:
- name: "repo1"
service_account_permissions:
- envvar_name: "AWS_ACCESS_KEY_ID_ACCOUNT_A"
ssm_parameter: "AccessKeyId-AccountA"
- envvar_name: "AWS_SECRET_ACCESS_KEY_ACCOUNT_A"
ssm_parameter: "SecretAccessKey-AccountA"
- envvar_name: "AWS_ACCESS_KEY_ID_ACCOUNT_B"
ssm_parameter: "AccessKeyId-AccountB"
- envvar_name: "AWS_SECRET_ACCESS_KEY_ACCOUNT_B"
ssm_parameter: "SecretAccessKey-AccountB"
service_account_list: "ACCOUNT_AACCOUNT_B"
The SSM parameters should exist.
The command to use to run this functionality is:
ansible-playbook aws-account-setup.yml \
--extra-vars=config_file=../aws-account-config-ixor/aws-account-config.yml \
--tags=bb
python3 -m venv ./venv
pip install boto boto3 ansible
. ./venv/bin/activate
ansible-galaxy collection install amazon.aws:1.5.1
ansible-galaxy collection install community.aws:1.5.0
ansible-playbook aws-account-setup.yml \
--extra-vars=config_file=../aws-account-config-ixor/aws-account-config.yml \
--tags=html
Note: The <accountname>
in subaccount_limit
can be a part of the accountname. That allows
you to provision multiple environments for the same project in one run:
... subaccount_limit=ixor.leveranciersportaal
will match:
ixor.leveranciersportaal-tst
ixor.leveranciersportaal-stg
ixor.leveranciersportaal-prd
ansible-playbook aws-account-setup.yml \
--extra-vars="config_file=../aws-account-config-ixor/aws-account-config.yml" \
--tags=accountalias
ansible-playbook aws-account-setup.yml \
--extra-vars="config_file=../aws-account-config-ixor/aws-account-config.yml" \
--tags=bastion
ansible-playbook aws-account-setup.yml \
--extra-vars="config_file=../aws-account-config-ixor/aws-account-config.yml subaccount_limit=<accountname>" \
--tags=subaccounts
ansible-playbook aws-account-setup.yml \
--extra-vars="config_file=../aws-account-config-ixor/aws-account-config.yml" \
--tags=tooling
ansible-playbook aws-account-setup.yml \
--extra-vars="config_file=../aws-account-config-ixor/aws-account-config.yml" \
--tags=security
ansible-playbook aws-account-setup.yml \
--extra-vars="config_file=../aws-account-config-ixor/aws-account-config.yml" \
--tags=monitoring
How long do these playbooks take to run?
bastion
part for 44 accounts: 20 minutes- The account setup for 1 account: about 90 seconds
- The
tooling
tasks take not more than a couple of minutes - The
monitoring
tasks: about 5 minutes (should not be limited to 1 account) - The
security
related actions: about 10 minutes (should not be limited to 1 account)
TODO ansible-playbook aws-account-setup.yml --extra-vars=config_file=../aws-account-config-ixor/aws-account-config.yml --tags=create_users