Reputation: 1698
I want to deploy my code to an EC2 instance, but I don't want to bake in the AWS Key and Secret. AWS Provides an IAM service to allow me to assign a role to my EC2 instances which will allow those instances access using temporary keys.
How do I get this to work? I have tried using the SDK and StsClient to assumeRole but this throws up an error
User: arn:aws:sts::XXXXXXXXXXXX:assumed-role/ROLE-NAME/INSTANCE No is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::XXXXXXXXXXXX:role/ROLE-NAME
Reading around and it seems that the STS request needs to use credentials itself to perform the Role assignment? but I thought that the EC2 instance keys would be used?
Upvotes: 5
Views: 2248
Reputation: 1698
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 :)
Upvotes: 8