Обновите файл с несколькими значениями автоматически.

Вопрос или проблема

У меня есть размещенная зона и набор записей, которые маршрутизируются на несколько адресов. Я хотел бы обновить набор записей, добавив или удалив один IP-адрес из списка. К сожалению, AWS CLI не предоставляет возможности удалять/добавлять значения ресурсной записи в route53.

{
      "Comment": "Обновить набор A-записей",
      "Changes": [
        {
          "Action": "UPSERT",
          "ResourceRecordSet": {
            "Name": "mydomain.com",
            "Type": "A",
            "TTL": 300,
            "ResourceRecords": [
              {
                "Value": "XX.XX.XX.XX"
              }
            ]
          }
        }
      ]
    }

Я могу вручную добавить несколько IP-адресов в ваш JSON вот так. Но я хочу автоматически добавлять несколько IP-адресов в файл JSON, используя bash.

{
    "Comment": "Обновить набор A-записей",
    "Changes": [{
        "Action": "UPSERT",
        "ResourceRecordSet": {
            "Name": "mydomain.com",
            "Type": "A",
            "TTL": 300,
            "ResourceRecords": [{
                    "Value": "XX.XX.XX.XX"
                },
                {
                    "Value": "XX.XX.XX.XX"
                }
            ]
        }
    }]
}

Добавление с использованием

$ jq '.Changes[0].ResourceRecordSet.ResourceRecords += [{"Value": "foobar"}]' file.json
{
  "Comment": "Обновить набор A-записей",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "mydomain.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "XX.XX.XX.XX"
          },
          {
            "Value": "foobar"
          }
        ]
      }
    }
  ]
}

вам может быть интересно попробовать другой утилит Unix: jtc, она способна вносить изменения в файл (с опцией -f):

bash $ jtc -w'<ResourceRecords>l' -i'{ "Value": "YY.YY.YY.YY" }' -f file.json
bash $ jtc file.json 
{
   "Changes": [
      {
         "Action": "UPSERT",
         "ResourceRecordSet": {
            "Name": "mydomain.com",
            "ResourceRecords": [
               {
                  "Value": "XX.XX.XX.XX"
               },
               {
                  "Value": "YY.YY.YY.YY"
               }
            ],
            "TTL": 300,
            "Type": "A"
         }
      }
   ],
   "Comment": "Обновить набор A-записей"
}
bash $ 

а также удаление записи(ей):

bash $ jtc -w'<ResourceRecords>l [0]' -p -f file.json
bash $ cat  file.json 
{
   "Changes": [
      {
         "Action": "UPSERT",
         "ResourceRecordSet": {
            "Name": "mydomain.com",
            "ResourceRecords": [
               {
                  "Value": "YY.YY.YY.YY"
               }
            ],
            "TTL": 300,
            "Type": "A"
         }
      }
   ],
   "Comment": "Обновить набор A-записей"
}
bash $ 

Допустим, у вас есть JSON подобный этому (здесь ResourceRecords является пустым массивом):

{
  "Comment": "Обновить набор A-записей",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "mydomain.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": []
      }
    }
  ]
}

… тогда вы можете добавить несколько записей типа { "Value": ipaddr } в этот массив ResourceRecord следующим образом:

jq '.Changes[0].ResourceRecordSet.ResourceRecords += ($ARGS.positional | map({Value: .}))' file.json --args a.a.a.a b.b.b.b c.c.c.c d.d.d.d

Это берет позиционные аргументы после --args (должно быть последним в командной строке) и преобразует каждый в объект с ключом Value. Созданные объекты затем добавляются в конец массива.

Результат:

{
  "Comment": "Обновить набор A-записей",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "mydomain.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "a.a.a.a"
          },
          {
            "Value": "b.b.b.b"
          },
          {
            "Value": "c.c.c.c"
          },
          {
            "Value": "d.d.d.d"
          }
        ]
      }
    }
  ]
}

Ответ или решение

Для выполнения автоматического обновления файла с несколькими значениями IP-адресов, необходимо использовать утилиты Unix, которые позволяют работать с JSON-данными. Одна из таких утилит — jq, другая — jtc. Ниже приведено детальное объяснение, как можно автоматически добавлять или удалять IP-адреса в Amazon Route 53, используя данные инструменты.

Теория

Amazon Route 53 управляет DNS записями для доменных имен. Ваша задача — обновить ресурсную запись (ResourceRecordSet), которая содержит список IP-адресов, путем добавления или удаления IP из этого списка. Однако AWS CLI не предоставляет встроенных функций для точечного удаления или добавления отдельных IP-адресов в таких ресурсных записях. Поэтому работа с JSON напрямую является наиболее подходящим решением.

Пример

Исходная JSON-структура, с которой мы будем работать, выглядит следующим образом:

{
    "Comment": "Update the A record set",
    "Changes": [{
        "Action": "UPSERT",
        "ResourceRecordSet": {
            "Name": "mydomain.com",
            "Type": "A",
            "TTL": 300,
            "ResourceRecords": []
        }
    }]
}

Для добавления IP-адресов вы можете использовать утилиту jq. Вот пример, как это делается:

jq '.Changes[0].ResourceRecordSet.ResourceRecords += ($ARGS.positional | map({Value: .}))' file.json --args a.a.a.a b.b.b.b c.c.c.c d.d.d.d

Команда jq берет позиционные аргументы после --args и каждый из них преобразует в объект с ключом Value, после чего добавляет эти объекты в массив IP-адресов.

Альтернативой jq является утилита jtc, которая тоже позволяет манипулировать JSON-файлами. Например:

  • Добавление нового IP:
jtc -w'<ResourceRecords>l' -i'{ "Value": "YY.YY.YY.YY" }' -f file.json
  • Удаление IP:
jtc -w'<ResourceRecords>l [0]' -p -f file.json

Применение

Предположим, у вас часто изменяются IP-адреса, и вам необходимо автоматизировать эти изменения. Вы могли бы создать скрипт на bash, который бы принимал аргументы и обновлял JSON-файл при помощи jq, а затем использовал бы AWS CLI для применения изменений.

Пример скрипта:

#!/bin/bash

# Файл с JSON
FILE="file.json"

# Проверка на наличие jq
if ! command -v jq &> /dev/null
then
    echo "jq is not installed. Please install jq first."
    exit
fi

# Добавление IP
jq --argjson ips "$(jq -n --arg ip "$*" '{Value: $ip}')" '.Changes[0].ResourceRecordSet.ResourceRecords += [$ips]' "$FILE" > tmp.$$.json && mv tmp.$$.json "$FILE"

# Команда для применения изменений посредством AWS CLI (пример)
# aws route53 change-resource-record-sets --hosted-zone-id ZZZZZZZZZZZZZZ --change-batch "file://$FILE"

Заключение

Автоматизация обновления записей в Route 53 через JSON-структуры позволяет значительно сократить ручной труд и минимизировать вероятность ошибок, связанных с человеческим фактором. Использование jq и jtc предоставляет гибкость в работе с JSON, а комбинирование этих утилит с мощными инструментами AWS открывает широкие возможности для управления DNS записями. Эти подходы и инструменты могут быть интегрированы в более широкую систему DevOps, обеспечивая надежное и быстрое обновление инфраструктурных данных.

Таким образом, эффективное и безопасное обновление IP в AWS является критически важным для поддержания актуальности и надежности сетевой инфраструктуры компании.

Оцените материал
Добавить комментарий

Капча загружается...