Correlation Between 3 Different Loops using Bash

I have 3 loops that I use to determine the permission level of AWS user accounts.

This array lists the AWS policy ARN (Amazon Resource Name):

for ((policy_index=0;policy_index<${#aws_managed_policies[@]};++policy_index)); do
          aws_policy_arn="${aws_managed_policies[policy_index]}"
          aws_policy_version_id=$(aws iam get-policy --policy-arn "$aws_policy_arn" --profile="$aws_key" | jq -r '.Policy.DefaultVersionId')
          readarray -t aws_policy_effects < <( if aws iam get-policy-version --policy-arn "$aws_policy_arn" --version-id "$aws_policy_version_id" --profile="$aws_key" 2> /dev/null | jq -r '.PolicyVersion.Document.Statement[].Effect' 2> /dev/null
          then
            true
          else
            aws iam get-policy-version --policy-arn "$aws_policy_arn" --version-id "$aws_policy_version_id" --profile="$aws_key" 2> /dev/null | jq -r '.PolicyVersion.Document.Statement.Effect' 2> /dev/null
          fi )
        done

I get the effect of the policy with this loop (Allow/Deny):

 for ((effect_index=0;effect_index<${#aws_policy_effects[@]};++effect_index)); do
        policy_effect="${aws_policy_effects[effect_index]}"
        echo "BEFORE IF STATEMENT: This is the policy effect: $policy_effect"
        if [[ "$policy_effect" = "Allow" ]]; then
            aws_policy_effects[effect_index]='ALLOW'
            unset aws_policy_effects
        elif [[ "$policy_effect" = "Deny" ]]; then
            aws_policy_effects[effect_index]='DENY'
        fi 
    done

And I get the list of services that the user has permission to with this loop:

  readarray -t aws_policy_actions < <(aws iam get-policy-version --policy-arn "$aws_policy_arn" --version-id "$aws_policy_version_id" --profile="$aws_key" 2> /dev/null | jq -r '.PolicyVersion.Document.Statement[].Action' 2> /dev/null  | grep '*')
    if [[ "$aws_policy_effect" = "Allow" ]]; then
        for ((action_index=0;action_index<${#aws_policy_actions[@]};++action_index)); do
            policy_action="${aws_policy_actions[action_index]}"
            if [[ "$policy_action" = "^*$" ]]; then
                admin_access="YES"
            elif [[ -n "$policy_action" ]]; then
                policy_action=$(echo "$policy_action" | cut -d: -f1)
                admin_access="YES"
                aws_admin_services+=("$policy_action")
            else
                admin_access="NO"              
            fi         
        done   # action loop
    fi

I want the 3 loops to correspond.

I need the ARN, Effect and Policies loops to agree: ARN1 with Effect 1 and Policy 1, ARN 2 with effect 2 and Policy 2, and so on.

How can I best achieve this? Do the 3 elements correspond with one another the way it's written? Or do I need to nest the 3 loops inside one another to do that?

I think you accidentally posted the same code twice.

Anyway, we have no idea where aws_policy_effects, etc came from, so we cannot possibly say what order they're in.

Also, you can shrink that loop a lot:

STR=""
for X in "${aws_policy_effects[@]}"
do
        [[ "$X" == "Deny" ]] && STR="$STR DENY" || STR="$STR ALLOW"
done
aws_policy_effects=( $STR ) # Do not quote, splitting is intentional

...but it might have been easier to just pipe the data through tr 'a-z' 'A-Z' in the first place.

I'm sure that last block of code could be shrank too.

Probably all of it could use a good looking over and rewriting.

1 Like