Reputation: 9415
In a solution, we are planning multiple clouds (AWS, Azure and GCP) as a solution. Same code will be deployed in multiple VMs running in different clouds.
In many cases, we need to detect cloud and write the code accordingly. e.g. Use AWS S3 SDK when running on AWS and Azure Blob SDK when running on Azure.
In AWS, we can hit metadata URL to detect (http://169.254.169.254/latest/meta-data/
) if it is AWS.
I am wondering if there is any way to detect the cloud provider inside the VM (like through environment variables or metadata URL or any other way).
Preferred code can be in python
or a shell script.
Upvotes: 2
Views: 1341
Reputation: 743
We may consider multiple ways to identify current Cloud relying to the instance metadata
Cloud-init
#! /bin/bash
# cloud-name, cloud_name, cloud_id, platform
cloud=$(cloud-init query cloud-name)
case ${cloud} in
aws) echo "AWS Cloud" ;;
azure) echo "Azure Cloud" ;;
gce) echo "GCP Cloud" ;;
*) echo "Unknown Cloud" ;;
esac
Metadata base URL
#! /bin/bash
# set -x -e
# AWS Cloud
token=$(curl -X PUT -s -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token)
status=$(curl -s -o /dev/null -w "%{http_code}" -H "X-aws-ec2-metadata-token: ${token}" http://169.254.169.254/latest/meta-data/)
[[ "${status}" -eq 200 ]] && cloud="aws"
# Azure Cloud
status=$(curl -s -o /dev/null -w "%{http_code}" -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata?api-version=2021-02-01&format=text")
[[ "${status}" -eq 200 ]] && cloud="azure"
# GCP Cloud
status=$(curl -s -o /dev/null -w "%{http_code}" -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/ || true)
[[ "${status}" -eq 200 ]] && cloud="gcp"
echo $cloud
Custom Tag/Metadata
For this example, we should set Tag Cloud=aws
on AWS, Cloud=azure
on Azure and Metadata Cloud=gcp
for GCP at instances creation.
#! /bin/bash
# set -x -e
# AWS Cloud
token=$(curl -X PUT -s -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token)
cloud_tag=$(curl -s -H "X-aws-ec2-metadata-token: ${token}" http://169.254.169.254/latest/meta-data/tags/instance/Cloud)
[[ "${cloud_tag}" == "aws" ]] && cloud="aws"
# Azure Cloud
cloud_tag=$(curl -s -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance/compute/tags?api-version=2021-02-01&format=text" | awk -F ';|Cloud:' '/Cloud/ {print $2}')
[[ "${cloud_tag}" == "azure" ]] && cloud="azure"
# GCP Cloud
cloud_tag=$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/attributes/Cloud || true)
[[ "${cloud_tag}" == "gcp" ]] && cloud="gcp"
echo $cloud
Additional information
Upvotes: 3
Reputation: 3553
With the answers of CSharpRocks and Dany L combined:
Azure:
http://169.254.169.254/metadata/instance?api-version=2021-02-01
http://metadata.google.internal/computeMetadata/v1
With header: Metadata-Flavor: Google
URL resolves to: http://169.254.169.254/
Amazon
http://169.254.169.254/latest/meta-data/
documentation:
Upvotes: 3