使用 lambda nodejs 更新 Route53 记录不起作用



我正在尝试使用 lambda 函数和 nodejs 运行时更新 Route53 中的记录。

问题是我没有收到任何错误,没有日志或 route53 中的任何内容,甚至无法理解它为什么不起作用。

我已经设置了以下内容:

  • λ函数
  • SNS 从中读取消息
  • 附加策略以更新/更改记录集

我的λ代码:

console.log('Running updateRecordSet');
/* global HOSTED_ZONE_ID*/
/* global DNS_RECORD_NAME*/
HOSTED_ZONE_ID = 'xxxx';
DNS_RECORD_NAME = 'dns-record.internal.example.com.';
var aws = require('aws-sdk');
var route53 = new aws.Route53();
exports.handler = async (event, context) => {
const message = event.Records[0].Sns.Message;
console.log('SNS message:', message);
try {
  const data = JSON.parse(message);
  if (data.ip) {
      console.log('New IP: ', data.ip);
      var newRecord = {
      HostedZoneId: HOSTED_ZONE_ID,
      ChangeBatch: {
        Changes: [{
          Action: 'UPSERT',
          ResourceRecordSet: {
            Name: DNS_RECORD_NAME,
            Type: 'A',
            ResourceRecords: [{Value: data.ip}],
            TTL: 30,
          }
        }]
      }
    };
    updateRecordSet(route53, DNS_RECORD_NAME, HOSTED_ZONE_ID, newRecord, function(err) {
              if (err) {
                return context.fail(err);
              }
              return context.succeed('OK');
            });
  }
} catch(err) {
    console.error(err);
}
return message;
};
function updateRecordSet(route53, DNS_RECORD_NAME, HOSTED_ZONE_ID, newRecord, callback) {
console.log("Executing function updateRecordSet");
route53.changeResourceRecordSets(newRecord, function(err) {
  if (err) {
    console.log("Got an err");
    return callback(err);
  }
  return console.log('Updated A record for', DNS_RECORD_NAME);
});
}

我得到输出:

Function Logs:
START RequestId: 4ef801ba-c03c-4582-33a8-c078c46f0b03 Version: $LATEST
2019-04-07T04:18:55.201Z    4ef801ba-c03c-4582-83a8-c078c46f0b03    SNS message: {"ip": "10.1.1.1"}
2019-04-07T04:18:55.201Z    4ef801ba-c03c-4582-83a8-c078c46f0b03    New IP:  10.1.1.1
2019-04-07T04:18:55.201Z    4ef801ba-c03c-4582-83a8-c078c46f0b03    Executing function updateRecordSet
END RequestId: 4ef801ba-c03c-4582-33a8-c078c46f0b03

如果 IAM 策略错误,我至少会收到某种身份验证错误?

由于

某种原因,我无法异步使用 lambda,但最终得到了工作代码。

此 lambda 将更新或插入 Route53 中从 SNS 读取的记录集,并显示类似 {"ip": "10.1.1.1"} 的 JSON 消息

console.log('Running updateRecordSet');
var AWS = require('aws-sdk');
/* global HOSTED_ZONE_ID*/
/* global DNS_RECORD_NAME*/
HOSTED_ZONE_ID = 'xxxxxx';
DNS_RECORD_NAME = 'dns-record.example.com.';
exports.handler = function(event, context, callback) {
  var route53 = new AWS.Route53();
  // Get message from SNS
  var message = event.Records[0].Sns.Message;
  const data = JSON.parse(message);
  if (typeof data.ip !== "undefined") {
    route53.changeResourceRecordSets({
      HostedZoneId : HOSTED_ZONE_ID,
      ChangeBatch : {
          Changes : [{
              Action: 'UPSERT',
              ResourceRecordSet: {
                  Name: DNS_RECORD_NAME,
                  Type: 'A',
                  ResourceRecords: [
                      {
                          Value: data.ip
                      }
                  ],
                  TTL: 30
              }
          }]
      }
    }, function (err, data) {
        if (err)
            console.log(err, err.stack);
        else {
            console.log('Updated Route53 DNS record ' + DNS_RECORD_NAME);
        }
    });
  } else {
    console.log('No IP found in message. Discarding.');
  }
};

如果你想有完整的承诺并等待事情的设置,你可以尝试下面的代码。它还有一些额外的东西,例如用于跨账户ROUTE53访问的 STS 代入角色。此外,它还具有创建多个 CNAME 的加权逻辑。我知道这不适合您的用例,但是它可能会帮助偶然发现类似问题的人使用 CNAME 创建加权负载平衡。

console.log('Running route53 changeRecrodSet with CNAME');
/* global HOSTED_ZONE_ID*/
/* global DNS_RECORD_NAME*/
const HOSTED_ZONE_ID = "xxxx";
const DNS_RECORD_NAME = "xxxxxx.com";
var AWS = require('aws-sdk');
AWS.config.region = 'us-west-1';
async function update_recordset(route53, records){
  return route53.changeResourceRecordSets(records).promise();
}
async function getcred(){
  console.log("inside getcred");
  var sts = new AWS.STS();
  try {
    let temp_cred = sts.assumeRole({
      RoleArn: 'arn:aws:iam::xxxxxxxx',
      RoleSessionName: 'awssdk'
    }).promise();
    console.log("TEMP",temp_cred);
    return temp_cred;
  }catch(err){
    console.log("ERROR",err);
  }
}

exports.handler = async (event) => {
  const message = event.Records[0].Sns.Message;
  console.log('SNS message:', message);
  try{
    const data = JSON.parse(message);
  if (data.cname) {
      console.log('New IP: ', data.cname);
    const sts_result = await getcred();
  console.log("STS_RESULT", sts_result);
  AWS.config.update({
        accessKeyId: sts_result.Credentials.AccessKeyId,
        secretAccessKey: sts_result.Credentials.SecretAccessKey,
        sessionToken: sts_result.Credentials.SessionToken
  });
  var route53 = new AWS.Route53();
  console.log("ROUTE53 RESULT",route53);
  const newRecord = {
        HostedZoneId: HOSTED_ZONE_ID,
        ChangeBatch: {
          Changes: [
            {
              Action: 'UPSERT',
              ResourceRecordSet: {
                SetIdentifier: "elb",
                Weight: 100,
                Name: DNS_RECORD_NAME,
                Type: 'CNAME',
                ResourceRecords: [{ Value: "xxxxx.sxxxxx.com" }],
                TTL: 300,
              },
            },
            {
              Action: 'UPSERT',
              ResourceRecordSet: {
                SetIdentifier: "cflare",
                Weight: 100,
                Name: DNS_RECORD_NAME,
                Type: 'CNAME',
                ResourceRecords: [{ Value: data.cname }],
                TTL: 300,
              },
            }],
        },
      };
    const results = await update_recordset(route53,newRecord); 
    console.log("Result", results);
  }
  }catch(err){
    console.log("ERR",err);
  }
};

你需要放置一个异步 - await 或只是回调((。两者都是一种不好的做法。我会做这样的事情:

console.log('Running updateRecordSet');
/* global HOSTED_ZONE_ID*/
/* global DNS_RECORD_NAME*/
HOSTED_ZONE_ID = 'xxxx';
DNS_RECORD_NAME = 'dns-record.internal.example.com.';
var aws = require('aws-sdk');
var route53 = new aws.Route53();
exports.handler = async (event) => {
const message = event.Records[0].Sns.Message;
console.log('SNS message:', message);
try {
  const data = JSON.parse(message);
  if (data.ip) {
      console.log('New IP: ', data.ip);
      var newRecord = {
      HostedZoneId: HOSTED_ZONE_ID,
      ChangeBatch: {
        Changes: [{
          Action: 'UPSERT',
          ResourceRecordSet: {
            Name: DNS_RECORD_NAME,
            Type: 'A',
            ResourceRecords: [{Value: data.ip}],
            TTL: 30,
          }
        }]
      }
    };
   let result = await route53.changeResourceRecordSets(newRecord);
   console.log(result);
  }
} catch(err) {
    console.error(err);
}
return message;
};

此外,您对 iam 角色的看法是正确的,如果您的代码正确运行所有函数,您将收到身份验证错误。

要让 async/await使用 AWS 开发工具包,您需要promisify 。请参阅下面的示例...

console.log('Running updateRecordSet');
/* global HOSTED_ZONE_ID*/
/* global DNS_RECORD_NAME*/
HOSTED_ZONE_ID = 'xxxx';
DNS_RECORD_NAME = 'dns-record.internal.example.com.';
const aws = require('aws-sdk');
const route53 = new aws.Route53();
const { promisify } = require('util');
const changeResourceRecordSets = promisify(route53.changeResourceRecordSets.bind(route53));
exports.handler = async (event) => {
  const message = event.Records[0].Sns.Message;
  console.log('SNS message:', message);
  try {
    const data = JSON.parse(message);
    if (data.ip) {
      console.log('New IP: ', data.ip);
      const newRecord = {
        HostedZoneId: HOSTED_ZONE_ID,
        ChangeBatch: {
          Changes: [
            {
              Action: 'UPSERT',
              ResourceRecordSet: {
                Name: DNS_RECORD_NAME,
                Type: 'A',
                ResourceRecords: [{ Value: data.ip }],
                TTL: 30,
              },
            }],
        },
      };
      const results = await changeResourceRecordSets(newRecord);
      if (results.ChangeInfo.Status === 'PENDING') {
        console.log('Updated A record for', DNS_RECORD_NAME, results);
        return {
          statusCode: 200,
          body: 'Success',
        };
      } else {
        console.error(results);
        return {
          statusCode: 500,
          body: 'Something went wrong',
        };
      }
    }
  } catch (err) {
    console.error(err);
  }
};

最新更新