Skip to content

Commit

Permalink
Allow external AWS accounts
Browse files Browse the repository at this point in the history
* This allows external (Non SSO Org accounts) to be initialised,
  bootstrapped and infrastructure deployed.
* When initialising an external account, it prompts the user to manually
  add a Role in the External account, with the required Trust
  Relationship provided. The Role name will be
  `<main-dalmatian-account-id>-dalmatian-access`.
* When generating the configuration, a profile will be added that uses
  the main dalmatian profile as a source profile, and the role arn of
  the role created in the External account. This creats an
  authentication flow of SSO Login -> Dalmatian Main -> External Account
  • Loading branch information
Stretch96 committed Mar 20, 2024
1 parent 65a8c75 commit c08eef5
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 10 deletions.
51 changes: 49 additions & 2 deletions bin/aws-sso/account-init
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ usage() {
echo " -i <aws_account_id> - AWS Account ID"
echo " -r <deefault_region> - AWS Default region"
echo " -n <account_name> - A lower case hyphenated friendly name"
echo " -e <external> - Configure as an 'External' AWS Account (An account not part of the SSO Org)"
exit 1
}

Expand All @@ -19,7 +20,8 @@ then
usage
fi

while getopts "i:r:n:h" opt; do
ACCOUNT_EXTERNAL=0
while getopts "i:r:n:eh" opt; do
case $opt in
i)
AWS_ACCOUNT_ID=$OPTARG
Expand All @@ -30,6 +32,9 @@ while getopts "i:r:n:h" opt; do
n)
ACCOUNT_NAME=$OPTARG
;;
e)
ACCOUNT_EXTERNAL=1
;;
h)
usage
;;
Expand All @@ -48,6 +53,49 @@ then
usage
fi

MAIN_DALMATIAN_ACCOUNT_ID="$(jq -r '.main_dalmatian_account_id' < "$CONFIG_SETUP_JSON_FILE")"
DALMATIAN_ACCOUNT_ADMIN_ROLE_NAME="$(jq -r '.aws_sso.default_admin_role_name' < "$CONFIG_SETUP_JSON_FILE")"

if [ "$ACCOUNT_EXTERNAL" == 1 ]
then
AWS_ACCOUNT_ID="E$AWS_ACCOUNT_ID"
EXTERNAL_ROLE_TRUST_RELATIONSHIP=$(
jq -n \
--arg aws_principal_arn "arn:aws:iam::$MAIN_DALMATIAN_ACCOUNT_ID:root" \
--arg sso_aws_principal_arn "arn:aws:iam::$MAIN_DALMATIAN_ACCOUNT_ID:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_${DALMATIAN_ACCOUNT_ADMIN_ROLE_NAME}_*" \
--arg sso_aws_principal_arn_wild_region "arn:aws:iam::$MAIN_DALMATIAN_ACCOUNT_ID:role/aws-reserved/sso.amazonaws.com/*/AWSReservedSSO_${DALMATIAN_ACCOUNT_ADMIN_ROLE_NAME}_*" \
'{
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Principal: {
AWS: $aws_principal_arn
},
Action: "sts:AssumeRole",
Condition: {
ArnLike: {
"aws:PrincipalArn": [
$sso_aws_principal_arn,
$sso_aws_principal_arn_wild_region
]
}
}
}
]
}'
)
echo "External accounts require a Role to be added that can be assumed by the AWS Federated user account from the Main Dalmatian account"
echo "1. In the External Account (${AWS_ACCOUNT_ID:1}), create a Role named '$MAIN_DALMATIAN_ACCOUNT_ID-dalmatian-access', which has Administrator permissions"
echo "2. Add the following Trust Relationship policy to the role:"
echo "$EXTERNAL_ROLE_TRUST_RELATIONSHIP"
echo "Note: If creating the role via the console, it will show the error: 'Invalid Global Condition Key'. This error can be ignored."
if ! yes_no "Enter 'y' to continue:" "y"
then
exit 0
fi
fi

NEW_WORKSPACE_NAME="$AWS_ACCOUNT_ID-$AWS_ACCOUNT_DEFAULT_REGION-$ACCOUNT_NAME"
echo "==> Creating $NEW_WORKSPACE_NAME workspace ..."

Expand Down Expand Up @@ -77,7 +125,6 @@ fi
if [ "$ACCOUNT_NAME" != "dalmatian-main" ]
then
echo "==> Running account bootstrap on the main Dalmatian account to upload tfvars ..."
MAIN_DALMATIAN_ACCOUNT_ID="$(jq -r '.main_dalmatian_account_id' < "$CONFIG_SETUP_JSON_FILE")"
DEFAULT_REGION="$(jq -r '.default_region' < "$CONFIG_SETUP_JSON_FILE")"
"$APP_ROOT/bin/dalmatian" deploy account-bootstrap -a "$MAIN_DALMATIAN_ACCOUNT_ID-$DEFAULT_REGION-dalmatian-main" -N
fi
Expand Down
27 changes: 19 additions & 8 deletions bin/aws-sso/generate-config
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,24 @@ do
SSO_CONFIG_ACCOUNT_ID="$(echo "$workspace" | cut -d"-" -f1)"
SSO_CONFIG_REGION="$(echo "$workspace" | cut -d"-" -f2-4)"
SSO_CONFIG_ACCOUNT_NAME="$(echo "$workspace" | cut -d"-" -f5-)"
append_sso_config_file \
"$CONFIG_AWS_SSO_FILE" \
"$SSO_CONFIG_ACCOUNT_NAME" \
"$AWS_SSO_START_URL" \
"$SSO_CONFIG_REGION" \
"$SSO_CONFIG_ACCOUNT_ID" \
"$DALMATIAN_ACCOUNT_ADMIN_ROLE_NAME" \
"$SSO_CONFIG_REGION"

if [[ "$SSO_CONFIG_ACCOUNT_ID" == E* ]]
then
EXTERNAL_ROLE_ARN="arn:aws:iam::${SSO_CONFIG_ACCOUNT_ID:1}:role/$DALMATIAN_ACCOUNT_ID-dalmatian-access"
append_sso_config_file_assume_role \
"$CONFIG_AWS_SSO_FILE" \
"$SSO_CONFIG_ACCOUNT_NAME" \
"dalmatian-main" \
"$EXTERNAL_ROLE_ARN"
else
append_sso_config_file \
"$CONFIG_AWS_SSO_FILE" \
"$SSO_CONFIG_ACCOUNT_NAME" \
"$AWS_SSO_START_URL" \
"$SSO_CONFIG_REGION" \
"$SSO_CONFIG_ACCOUNT_ID" \
"$DALMATIAN_ACCOUNT_ADMIN_ROLE_NAME" \
"$SSO_CONFIG_REGION"
fi
fi
done < <("$APP_ROOT/bin/dalmatian" terraform-dependencies run-terraform-command -c "workspace list" -a -q)
20 changes: 20 additions & 0 deletions lib/bash-functions/append_sso_config_file_assume_role.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
set -e
set -o pipefail

# Dalmatian specific function
# Appends a profile which assumes a role to the
# configuration file
function append_sso_config_file_assume_role {
config_file="$1"
profile_name="$2"
source_profile="$3"
role_arn="$4"

cat <<EOT >> "$config_file"
[profile $profile_name]
source_profile = $source_profile
role_arn = $role_arn
EOT
}

0 comments on commit c08eef5

Please sign in to comment.