Я один из ведущих абонентов Pagerduty Terraform Provider Что означает, что я пишу много Terraform Определения в Язык конфигурации hashicorp (HCL) . Сам поставщик содержит здоровую коллекцию приемлемовых тестов, но я часто все еще пишу некоторые из своих собственных HCL, чтобы проверить варианты использования и убедиться, что исправления ошибок решают конкретные проблемы, поднятые пользователями.
Чтобы создать эти определения терраформы, я обычно пишу HCL вручную. Тем не менее, это может стать утомительным, если мне нужно создать, скажем, 150 из того же ресурса для тестирования Парень исходя из PAGERDUTY API Анкет Исторически я использовал сценарий Python, который условно выписал синтаксис HCL, как SO SO
def createService(label, id, output): tf_code = "resource \"pagerduty_service\" \""+id+"\" {\n\ name = \""+label+"\"\n\ escalation_policy = pagerduty_escalation_policy."+str(id)+".id \n\ alert_creation = \"create_alerts_and_incidents\" \n\ }\n\n" output.write(tf_code)
Функции, подобные этому CreateService
Выше будет написано для каждого ресурса и помещается внутрь цикла для создания блоков ресурсов HCL, которые были необходимы для определения. Честно говоря, этот метод работал нормально для меня. По крайней мере, это произошло, пока я не подумал, не обеспечил ли Go лучше. Вот когда я обнаружил HclWrite Пакет от hashicorp.
Документация по проекту описывает HCLWRITE как пакет, который «решает проблему создания конфигурации HCL и внесения конкретных хирургических изменений в существующих конфигурациях HCL. «Это оказалось именно тем пакетом, в котором я нуждался. Вместо того, чтобы записывать синтаксис HCL вручную, пакет HCLWRITE сделал бы это для меня, в то время как я только что называл функции для создания объектов.
Эта статья поможет вам начать работу с пакетом HCLWRITE, пройдя вас через то, как я использовал ее для создания конфигурации Terraform для создания 150 бизнес -услуг в PagerDuty. Я пройду через некоторые из концепций, с которыми я боролся, и хотел, чтобы было больше примеров.
Пакет HclWrite импортируется из github.com/hashicorp/hcl/hclwrite
Анкет Это немного разбило меня, отчасти потому, что я все еще относительно новый, чтобы идти и отчасти потому, что путь к пакету, указанный в документации, немного отличается. Для всех вас также новичок, ваш импорт должен выглядеть примерно так:
import ( "fmt" "os" "github.com/hashicorp/hcl/hclwrite" "github.com/zclconf/go-cty/cty" )
Вы заметите еще один импорт для go-cty упаковка. Этот пакет (произносимый вид) предоставляет некоторую инфраструктуру для системы типа, которая может быть полезна для приложений, которые необходимо представлять значения конфигурации. Вы увидите, что он используется в примерах при настройке типов для атрибута значений.
Чтобы начать вещи, вам понадобится создание двух разных типов файловых объектов. Один для HclWrite и другой для файловой системы. Это можно сделать со следующим кодом.
// create new empty hcl file object hclFile := hclwrite.NewEmptyFile() // create new file on system tfFile, err := os.Create("bservelist.tf") if err != nil { fmt.Println(err) return } // initialize the body of the new file object rootBody := hclFile.Body()
Содержание каждого объекта в HclWrite хранится в объекте тела. Чтобы добавить или добавить что -либо в объект, который вам понадобится, чтобы ссылаться на его тело. В приведенном выше коде вы видите, что мы назвали тело объекта документа HCL rootbody
Анкет Первое, что нам нужно сделать с rootbody
настроен поставщик
Блок для PAGERDUTY Provider Анкет HCl для этого блока выглядит так
provider "pagerduty" { token = "yeahRightN0tgo1ng2t3llyOuTh@t" }
Создание этого блока с помощью HclWrite
Пакет требует Appendnewblock функция, которая ожидает два аргумента. Во -первых, это строка, которая установит тип блока, а второй аргумент — это массив строк, которые действуют как метки для блока. В случае этого поставщик
Блок Мы хотим установить этикетку просто как Pagerduty
Анкет Это выглядело бы примерно так:
provider := rootBody.AppendNewBlock("provider", []string{"pagerduty"})
Внутри этого блока нам нужно установить токен
атрибут значению ключа Pagerduty API. Помните, атрибут должен быть добавлен в тело блока. Итак, мы сначала установим это значение тела на поставщик тело
переменная, а затем вызовите SetAttributeValue , передавая этикетку и значение атрибута в качестве аргументов.
providerBody := provider.Body() providerBody.SetAttributeValue("token", cty.StringVal(os.Getenv("PAGERDUTY_TOKEN")))
Следующий блок, который мы собираемся создать, — это Terraform
Блок, где мы определяем, какие поставщики мы собираемся использовать, и версии этих поставщиков. Что интересно в этих определениях, так это то, что им требуются два вложенных блока, в которых нет никаких ярлыков. Appendnewblock
Функция обрабатывает его, принимая Ниль
Аргумент для ярлыков. Создание двух блоков выглядит так:
tfBlock := rootBody.AppendNewBlock("terraform", nil) tfBlockBody := tfBlock.Body() reqProvsBlock := tfBlockBody.AppendNewBlock("required_providers", nil) reqProvsBlockBody := reqProvsBlock.Body()
Внутри Обязательный_провиденс
Блок нам нужно определить атрибут с именем Pagerduty
Это содержит значение объекта с двумя парами ключей в виде полей. Это делается путем установки значения на Cty. ObjectVal
как карта.
reqProvsBlockBody.SetAttributeValue("pagerduty", cty.ObjectVal(map[string]cty.Value{ "source": cty.StringVal("PagerDuty/pagerduty"), "version": cty.StringVal("1.10.1"), }))
Сгенерированный HCl для этого кода будет выглядеть следующим образом:
terraform { required_providers { pagerduty = { source = "PagerDuty/pagerduty" version = "1.10.1" } } }
Теперь пришло время начать создавать фактические ресурсы. Помните, что наша задача состояла в том, чтобы создать 150 бизнес -сервисов. В HCL блок ресурсов похож на другие типы блоков, которые мы создали. Основное различие в том, что блоки ресурсов содержат несколько ярлыков. В этом случае каждый блок ресурса содержит pagerduty_business_service
Метка для типа ресурса вместе с меткой идентификатора для ресурса. Поскольку мы заботимся только о создании большого количества бизнес -услуг, не имеет значения, как они назвали. Итак, мы просто собираемся использовать индекс я
От нашего цикла, чтобы поместить числовую переменную в каждое название бизнес -услуги. Например, название первой бизнес -службы будет «Бизнес -служба 1». Код для создания этих блоков ресурсов выглядит так:
bs := rootBody.AppendNewBlock("resource", []string{"pagerduty_business_service", fmt.Sprintf("bs%v", i)}) bsBody := bs.Body() bsBody.SetAttributeValue("name", cty.StringVal(fmt.Sprintf("Business Service %v", i))) rootBody.AppendNewline()
Когда зацикливание будет сделано, и HCL для всех 150 определений бизнес -сервисов был сгенерирован, последнее, что нужно сделать, это написать все определения на .tf
файл. Есть несколько способов сделать это. Я пошел на то, как я был наиболее знаком, где я написал байты из HclWrite
Файл объект в ТФФЛИЛ
, как это:
tfFile.Write(f.Bytes())
И это все. Вы должны быть в состоянии запустить конфигурации в .tf
Файл, который вы создали и заполняли. Чтобы увидеть весь код, используемый в этих примерах. Проверьте Создайте файлы Terraform в go Проект на GitHub. Это было также только введение в HclWrite
упаковка. Иди посмотреть hclwrite документация Чтобы увидеть все доступные функции.
Оригинал: «https://dev.to/pdcommunity/write-terraform-files-in-go-with-hclwrite-2e1j»