Question: I'm confused by what `declare -A` does here, could somebody explain?

```
declare -A deploy
roles="test1 test2 test3 test4"

for role in $roles; do
    deploy[$role]=${!role}
done

```

More confuse about `${!role}`

Answer: 
`declare -A` defines an associative array, one that can map a string to another string.

For example:

```
pax> declare -A mymap

pax> mymap[washington]=george
pax> mymap[lincoln]=abe

pax> echo ${!mymap[*]}
washington lincoln

pax> echo ${mymap[no_such_key]}

pax> echo ${mymap[washington]}
george

pax> echo ${mymap[lincoln]}
abe

```

---

In terms of the `${!role}` bit, this is indirect expansion. Normally, a variable will have one level of expansion as you can see below:

```
pax> plugh=xyzzy
pax> xyzzy=zorkmid
pax> echo ${plugh}
xyzzy

```

However, you can also treat the expansion of the name as another *variable* which is subsequently expanded:

```
pax> echo ${!plugh}
zorkmid

```

What happens there is that the `plugh` is expanded to `xyzzy`, then that itself is expanded again to `zorkmid`.

In your *specific* case where, for example, the variable `role` is set to `test1`, the following lines are equivalent:

```
deploy[$role]=${!role}
deploy[test1]=${test1}

```
`declare -A deploy` marks `deploy` as the name of an associative array, one that maps one string to another.

Each time through the loop, a different word from the expansion of `$roles` is added as a new key to the array. `${!role}` is indirect parameter expansion, expanding to the value of the variable whose name is the value of `$role`. The loop is equivalent to

```
deploy[test1]=$test1
deploy[test2]=$test2
deploy[test3]=$test3
deploy[test4]=$test4

```