简体   繁体   中英

AWS STS Roles with EC2 AssumeRole

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?

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 :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM