Yes the STS call to assume role DOES need credentials to work, however it uses the credentials provided when it is constructed, if these are omitted it doesn't fall back to instance based credentials.
To use instance based credentials to make the call you need to use something like :
$credentials = \Aws\Credentials\CredentialProvider::instanceProfile();
Which will fetch the name of the associated role, and then the temp instance credentials. If you know the name of the role you can specify it in the constructor
$credentials = \Aws\Credentials\CredentialProvider::instanceProfile(['profile' => 'role-name-here']);
You will also need to update the Trust Relationship on the role to allow the instance to assume the role. I assumed the Service entry would do this however changing this to reference the IAM role seems to work
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::XXXXXXXXXXXX:role/ROLE-NAME"
},
"Action": "sts:AssumeRole"
}
(Don't forget to add the comma on the end of the previous sections closing } )
Now pass those credentials into the constructor of the Sts client and your call to AssumeRole should return successfully. My test code for this is:
$credentials = \Aws\Credentials\CredentialProvider::instanceProfile();
$stsClient = new \Aws\Sts\StsClient(['region' => 'eu-west-1', 'version' => 'latest', 'credentials' => $credentials]);
$ar = $stsClient->assumeRole(['RoleArn' => 'arn:aws:iam::XXXXXXXXXXXX:role/Ec2Role-queue', 'RoleSessionName' => 'test']);
$creds = $stsClient->createCredentials($ar);
var_dump($creds);
Which outputs :
object(Aws\Credentials\Credentials)#96 (4) {
["key":"Aws\Credentials\Credentials":private]=>
string(20) "XXXXIYH36RJ5NZCDXXXX"
["secret":"Aws\Credentials\Credentials":private]=>
string(40) "eXXXX+azLUNi9LjwyX4MkNI4rnEpFrG9pNNXXXXX"
["token":"Aws\Credentials\Credentials":private]=>
string(308) "FQoDYXdzEH4aDIa3Rx/onWIa4ArZeyLHAX+muL7zKt9trAQhMa98pkzpGGmOGa0N5UhCjX2GXQ3Dc2APElwlpCfr9F+J2k5igAeonadgrwAOC/OvEDv34i1JdmkaUjEE14S2hVGz2dXXXXegYra7kvx0cdoOjCPIFmXSZJeD1PR27lFyacH2x5+F1XKFugveiYCD63axATp4t8fq0K+EPjXXXX/wYKm5tJt7hYkCV7+tThLYFDPZ6NkXXXXjsSKkOw9u52yGJY4yD50y+liSprHH+/ZJyQppDIJcZbbpyBoojoeRvwU="
["expires":"Aws\Credentials\Credentials":private]=>
int(1474580894)
}
Hopefully that helps someone else save a few hair follicles :)