Рубрики
Uncategorized

Напишите файлы Terraform in go with hclwrite

Я являюсь одним из ведущих поставщиков провайдера Terraform Pagerduty, что означает, что я нахожу … Tagged with Go, Terraform, DevOps.

Я один из ведущих абонентов 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»