Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New feature: terraform target by tags #685

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
5 changes: 5 additions & 0 deletions docs/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,11 @@ pipeline for more details in the setup and integration.
- `TARGET_ACCOUNTS`: comma separated list of target accounts.
- `TARGET_OUS`: comma separated list of target leaf OUs (parent
OUs are supported).
- `TARGET_TAGS`: comma separated list of tag=value couples. All accounts
matching at least one of the tags will be targeted by the pipeline.

**Eg:** `TARGET_TAGS=environment=prd,cost-center=ccoe` will match all
accounts tagged with `environment = prd` OR `cost-center = ccoe`
igordust marked this conversation as resolved.
Show resolved Hide resolved
- `REGIONS`: comma separated list of target regions. If this parameter
is empty, the main ADF region is used.
- `MANAGEMENT_ACCOUNT_ID`: id of the AWS Organizations management account.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Resources:
- organizations:ListOrganizationalUnitsForParent
- organizations:ListRoots
- organizations:ListChildren
- organizations:ListTagsForResource
- tag:GetResources
Resource: "*"
Roles:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ do
AWS_REGION=$(echo -n "$REGION" | sed 's/^[ \t]*//;s/[ \t]*$//') # sed trims whitespaces
export TF_VAR_TARGET_REGION=$AWS_REGION
# if TARGET_ACCOUNTS and TARGET_OUS are not defined apply to all accounts
if [[ -z "$TARGET_ACCOUNTS" ]] && [[ -z "$TARGET_OUS" ]]
if [[ -z "$TARGET_ACCOUNTS" ]] && [[ -z "$TARGET_OUS" ]] && [[ -z "$TARGET_TAGS" ]]
then
echo "Apply to all accounts"
for ACCOUNT_ID in $(jq '.[].AccountId' "${CURRENT}/accounts.json" | sed 's/"//g' )
Expand All @@ -124,4 +124,13 @@ do
tfrun
done
fi

if ! [[ -z "$TARGET_TAGS" ]]
then
echo "List target TAGS: $TARGET_TAGS"
for ACCOUNT_ID in $(jq '.[].AccountId' "${CURRENT}/accounts_from_tags.json" | sed 's/"//g' )
do
tfrun
done
fi
done
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

MANAGEMENT_ACCOUNT_ID = os.environ["MANAGEMENT_ACCOUNT_ID"]
TARGET_OUS = os.environ.get("TARGET_OUS")
TARGET_TAGS = os.environ.get("TARGET_TAGS")
REGION_DEFAULT = os.environ["AWS_REGION"]
PARTITION = get_partition(REGION_DEFAULT)
sts = boto3.client('sts')
Expand All @@ -38,6 +39,12 @@ def main():
with open('accounts_from_ous.json', 'w', encoding='utf-8') as outfile:
json.dump(accounts_from_ous, outfile)

if TARGET_TAGS:
print("filtering by tags")
igordust marked this conversation as resolved.
Show resolved Hide resolved
accounts_from_tags = get_accounts_from_tags()
with open('accounts_from_tags.json', 'w', encoding='utf-8') as outfile:
json.dump(accounts_from_tags, outfile)


def list_organizational_units_for_parent(parent_ou):
organizations = get_boto3_client(
Expand Down Expand Up @@ -90,6 +97,45 @@ def get_accounts():
)


def get_accounts_from_tags():
accounts = get_accounts()
tag_filters = []
for tag in TARGET_TAGS.split(','):
tag_name = tag.split('=')[0]
tag_value = tag.split('=')[1]
tag_filters.append({
"Key": tag_name,
"Value": tag_value})

LOGGER.info(
"Tag filters %s",
tag_filters
)

organizations = get_boto3_client(
'organizations',
(
f'arn:{PARTITION}:sts::{MANAGEMENT_ACCOUNT_ID}:role/'
f'{CROSS_ACCOUNT_ACCESS_ROLE}-readonly'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be updated to the new role added in v4.

),
'getaccountIDs',
)
filtered_accounts = []
for account in accounts:
tags = account['Tags'] = organizations.list_tags_for_resource(
igordust marked this conversation as resolved.
Show resolved Hide resolved
ResourceId=account['AccountId']
)['Tags']
for tag_filter in tag_filters:
found = list(filter(lambda item: (
item["Key"] == tag_filter["Key"] and item["Value"] == tag_filter["Value"]), tags))
if len(found) > 0:
print(
igordust marked this conversation as resolved.
Show resolved Hide resolved
f"{account['AccountId']} matched {tag_filter['Key']}={tag_filter['Value']}")
filtered_accounts.append(account)
break
return filtered_accounts


def get_accounts_from_ous():
parent_ou_id = None
account_list = []
Expand Down