The 169.254.169.254 address
The 169.254.169.254 endpoint can be reached by an EC2 instance locally during runtime. The address provides all sorts of meta data which helps to operate, audit, maintain an instance during its life time.
The pseudo address can be reached locally only (on the instance):
http://169.254.169.254/latest/meta-data/
Beside meta data information such like ami-id, hostname, instance-id, placement (so the AZ, availability zone) it also provides security related information.
Example:
curl http://169.254.169.254/latest/meta-data/instance-type
m5.xlarge
If utilized correctly the information provided through the 169.254.169.254 endpoint provides tremendous help to maintain code more effectively, get risk risks reduced where access keys may be leaked into code, code repositories (git, svn) or even may be posted in documentation. Depending to what policy would be attached to those keys it could open high security concerns.
Increased security and simplified code
As an IAM profile can be assigned to any EC2 instance (one at a time) it allows to increase security significantly and on top to let key handling become much easier. The need to share keys, the risk to have them embedded in code, the need to track keys to get them rotated and such can be eliminated in favor towards higher security.
Example:
#curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role name>
{
“Code” : “Success”,
“LastUpdated” : “2020-11-19T16:47:54Z”,
“Type” : “AWS-HMAC”,
“AccessKeyId” : “ABCDEFGHIJKLMNOPQRST”,
“SecretAccessKey” : “1234567890ABCDEFGHIJKLMNOPQRST”,
“Token” : “…”,
“Expiration” : “2020-11-19T23:14:05Z”
}
The official documents are provided at AWS here.
Code samples
PHP
GetRegion reads the placement information from the pseudo address at http://169.254.169.254/latest/meta-data/placement. With the CredentialsProvider::instanceProfile() it allows to avoid configuration handling as described.
public function __construct()
{
$provider = CredentialProvider::instanceProfile();
$memoizedProvider = CredentialProvider::memoize($provider);
$this->awsclient = new Client(
array(
'credentials' => $memoizedProvider,
'region' => $this->GetRegion();
'version' => 'latest'
)
);
}
Python
session = boto3.Session(region_name=Region)
credentials = session.get_credentials()
credentials = credentials.get_frozen_credentials()
Key = credentials.access_key
Secret = credentials.secret_key
Token = credentials.token
client = boto3.client('',
aws_access_key_id=Key,
aws_secret_access_key=Secret,
aws_session_token=Token,
region_name=Region
)