Search code examples
amazon-web-servicesaws-php-sdk

AWS SDK: How to get the response body for a 404


I'm attempting to access a remote GraphQL server used by a publicly available web site. I've pieced together the appropriate code to interact with the database and can run it locally successfully. It involves me getting some createCognitoIdentity() credentials and then using those credentials to send a GraphQL query. Works like a charm and I get the data I'm looking for... until deployed to prod.

Once in prod, the same code produces a 404 error and I'm unable to even try to query the db because getting the credentials fails with:

Error retrieving credentials from the instance profile metadata service. (Client error: GET http://169.254.169.254/latest/meta-data/iam/security-credentials/ resulted in a 404 Not Found response: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww (truncated...) )

Here's my code to recreate it:

$sdk = (new \Aws\Sdk([
    'region' => 'us-east-2',
    'version' => 'latest',
]));
$result = $sdk->createCognitoIdentity()->getCredentialsForIdentity([
    'IdentityId' => 'us-east-2:3945b61f-5ad6-4e57-b7bf-2d01874e94d4',
]);

My production environment is hosted within AWS, so I suspect it's possible the 404 is because it's within AWS? Seems strange to add such a restriction. I'd like to rule out any potential xml present within the response body, but I'm having trouble obtaining the full body.

How can I echo out the response body when a 404 is encountered?


Solution

  • The issue you're having is that there are no IAM credentials associated with the EC2. I have an EC2 that has an IAM role tied to it. To check this I run:

    curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
    

    On the instances with an IAM role attached I get the role name that is attached - nothing but the name (i.e. no HTML or anything else). On another instance that has no credentials and running the same command I get:

    <?xml version="1.0" encoding="iso-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
     <head>
      <title>404 - Not Found</title>
     </head>
     <body>
      <h1>404 - Not Found</h1>
     </body>
    </html>
    

    which looks like what you're getting. This is from the command line but cURL should get you almost the exact same thing in PHP.

    Edit based on the comments

    It sounds like the challenge is ultimately that your development environment has credentials set but your EC2 doesn't. The error is a bit misleading as it's ultimately a permission denied (as there are no credentials) but it's surfaced as a 404 because there isn't anything in the metadata.

    There is more information here regarding the use of instance profiles. As you're using a Docker to deploy and based on this post the container should be able to get the same profile as if you were running natively.