Search code examples
node.jstypescriptswaggercontainersamazon-ecs

How to fetch aws ecs container ip address in nodejs project


I have uploaded my API project (Node.js project) to AWS ECS container and my project contains swagger documentation. In swagger I want to indicate the current host Ip address that the API is run on but I cannot find the right code to fetch it. There is a solution for that? since I have managed to implement it on .NetCore API.

How does it looks right now:
How does it looks right now

Thx in advance.


Solution

  • You can make use of AWS ECS metadata endpoint http://172.17.0.1:51678/v1/metadata from an ECS task to fetch details about the container instance. The details fetched can then be used to get the private/public ip address of the instance. Example:

    import http from 'http';
    import util from 'util';
    import AWS from 'aws-sdk';
    
    export const getIPAddresses = async () => {
      try {
        let options: any = {
          hostname: '172.17.0.1',
          port: 51678,
          path: '/v1/metadata',
          method: 'GET'
        }
        let containerInstanceDetails: any = await httpGet(options);
        containerInstanceDetails = JSON.parse(containerInstanceDetails);
        const cluster = containerInstanceDetails["Cluster"];
        const containerInstanceArn = containerInstanceDetails["ContainerInstanceArn"];
        const containerInstanceUUID = containerInstanceArn.split('/')[2];
        let params: any = {
          cluster: cluster,
          containerInstances: [containerInstanceUUID]
        }
    
        if (!AWS.config.region) {
          AWS.config.update({
            region: <your_aws_region>
          });
        }
    
        const ecs = new AWS.ECS({ 'region': <your_aws_region> });
        const ec2 = new AWS.EC2({ 'region': <your_aws_region> });
    
        const describeContainerInstancesAsync = util.promisify(ecs.describeContainerInstances).bind(ecs);
        const describeInstancesAsync = util.promisify(ec2.describeInstances).bind(ec2);
        let data = await describeContainerInstancesAsync(params);
        const ec2InstanceId = data.containerInstances[0].ec2InstanceId;
    
        params = {
          InstanceIds: [
            ec2InstanceId
          ]
        }
    
        data = await describeInstancesAsync(params);
        return [data.Reservations[0].Instances[0].PrivateIpAddress, data.Reservations[0].Instances[0].PublicIpAddress];
      }
      catch(err) {
        console.log(err);
      }
    }
    
    async function httpGet(options) {
      return new Promise((resolve, reject) => {
        http.get(options, response => {
          response.setEncoding('utf8');
          response.on('data', data => {
            resolve(data);
          });
        }).on('error', error => {
          reject(error.message);
        });
      });
    }