Heim >Backend-Entwicklung >Golang >Wie kann ich ein Golang-Skript Werte in einer Terraform-Datei (HCL-Format) ändern lassen?

Wie kann ich ein Golang-Skript Werte in einer Terraform-Datei (HCL-Format) ändern lassen?

WBOY
WBOYnach vorne
2024-02-09 12:06:28916Durchsuche

如何让 Golang 脚本修改 Terraform(HCL 格式)文件中的值?

php-Editor Youzi zeigt Ihnen, wie Sie mit dem Golang-Skript den Wert in einer Terraform-Datei (HCL-Format) ändern. Terraform ist ein Infrastructure-as-Code-Tool, das uns bei der Verwaltung und Automatisierung der Cloud-Infrastruktur hilft. Wenn wir jedoch häufig bestimmte Werte in der Terraform-Datei ändern müssen, werden manuelle Vorgänge sehr mühsam. Daher ist die Verwendung von Golang-Skripten zum Ändern von Werten in Terraform-Dateien eine effizientere Methode. In diesem Artikel zeige ich Ihnen, wie Sie mit Golang ein Skript schreiben, um dies zu erreichen, damit Sie Werte in Terraform-Dateien einfach ändern können.

Frageninhalt

Ich versuche, eine kleine Automatisierung an einer Terraform-Datei vorzunehmen, die eine Azure-Netzwerksicherheitsgruppe definiert. Im Wesentlichen habe ich eine Website und SSH-Zugriff. Ich möchte nur meine öffentliche IP-Adresse zulassen, auf die ich über den Wert icanhazip.com 获取该地址。我希望使用 golang 脚本将我的 ip 写入 .tf 文件的相关部分(本质上是设置 security_rule.source_address_prefixes zugreifen kann.

Ich versuche, hclsimple 库,并尝试了 gohclhclwrite usw. in Golang zu verwenden, aber im Wesentlichen mache ich keine Fortschritte bei der Konvertierung von HCL-Dateien in Golang-Strukturen.

Meine Terraform-Datei (im HCL-Format, glaube ich) sieht so aus:

resource "azurerm_network_security_group" "my_nsg" {
  name                = "my_nsg"
  location            = "loc"
  resource_group_name = "rgname"

  security_rule       = [
           {
               access                                     = "deny"
               description                                = "desc"
               destination_address_prefix                 = "*"
               destination_address_prefixes               = []
               destination_application_security_group_ids = []
               destination_port_range                     = ""
               destination_port_ranges                    = [
                   "123",
                   "456",
                   "789",
                   "1001",
                ]
               direction                                  = "inbound"
               name                                       = "allowinboundthing"
               priority                                   = 100
               protocol                                   = "*"
               source_address_prefix                      = "*"
               source_address_prefixes                    = [
                  # obtain from icanhazip.com
                  "1.2.3.4"
               ]
               source_application_security_group_ids      = []
               source_port_range                          = "*"
               source_port_ranges                         = []
            },
           {
               access                                     = "allow"
               description                                = "grant acccess to app"
               destination_address_prefix                 = "*"
               destination_address_prefixes               = []
               destination_application_security_group_ids = []
               destination_port_range                     = ""
               destination_port_ranges                    = [
                   "443",
                   "80",
                ]
               direction                                  = "inbound"
               name                                       = "allowipinbound"
               priority                                   = 200
               protocol                                   = "*"
               source_address_prefix                      = ""
               source_address_prefixes                    = [
                # obtain from icanhazip.com
                   "1.2.3.4"
                ]
               source_application_security_group_ids      = []
               source_port_range                          = "*"
               source_port_ranges                         = []
            }
        ]
}

Das habe ich bekommen, als mein Golang-Skript versuchte, die oben genannten Daten als Struktur darzustellen und dann die .tf-Datei selbst zu dekodieren (ich habe ein paar Methoden lokal von hclsimple kopiert, damit es die .tf-Datei wie in der Dokumentation vorgeschlagen dekodiert Dokumente

package main

import (
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "os"
    "path/filepath"
    "strings"

    "github.com/hashicorp/hcl/v2"
    "github.com/hashicorp/hcl/v2/gohcl"
    "github.com/hashicorp/hcl/v2/hclsimple"
    "github.com/hashicorp/hcl/v2/hclsyntax"
    "github.com/hashicorp/hcl/v2/json"
)

type config struct {
    networksecuritygroup []networksecuritygroup `hcl:"resource,block"`
}

type networksecuritygroup struct {
    type              string         `hcl:"azurerm_network_security_group,label"`
    name              string         `hcl:"mick-linux3-nsg,label"`
    nameattr          string         `hcl:"name"`
    location          string         `hcl:"location"`
    resourcegroupname string         `hcl:"resource_group_name"`
    securityrule      []securityrule `hcl:"security_rule,block"`
}

type securityrule struct {
    access                                 string   `hcl:"access"`
    description                            string   `hcl:"description"`
    destinationaddressprefix               string   `hcl:"destination_address_prefix"`
    destinationaddressprefixes             []string `hcl:"destination_address_prefixes"`
    destinationapplicationsecuritygroupids []string `hcl:"destination_application_security_group_ids"`
    destinationportrange                   string   `hcl:"destination_port_range"`
    destinationportranges                  []string `hcl:"destination_port_ranges"`
    direction                              string   `hcl:"direction"`
    name                                   string   `hcl:"name"`
    priority                               int      `hcl:"priority"`
    protocol                               string   `hcl:"protocol"`
    sourceaddressprefix                    string   `hcl:"source_address_prefix"`
    sourceaddressprefixes                  []string `hcl:"source_address_prefixes"`
    sourceapplicationsecuritygroupids      []string `hcl:"source_application_security_group_ids"`
    sourceportrange                        string   `hcl:"source_port_range"`
    sourceportranges                       []string `hcl:"source_port_ranges"`
}

func main() {
    // lets pass this in as a param?
    configfilepath := "nsg.tf"

    // create new config struct
    var config config

    // this decodes the tf file into the config struct, and hydrates the values
    err := mydecodefile(configfilepath, nil, &config)
    if err != nil {
        log.fatalf("failed to load configuration: %s", err)
    }
    log.printf("configuration is %#v", config)

    // let's read in the file contents
    file, err := os.open(configfilepath)
    if err != nil {
        fmt.printf("failed to read file: %v\n", err)
        return
    }
    defer file.close()

    // read the file and output as a []bytes
    bytes, err := io.readall(file)
    if err != nil {
        fmt.println("error reading file:", err)
        return
    }

    // parse, decode and evaluate the config of the .tf file
    hclsimple.decode(configfilepath, bytes, nil, &config)

    // iterate through the rules until we find one with
    // description = "grant acccess to flask app"

    // code go here
    for _, nsg := range config.networksecuritygroup {
        fmt.printf("security rule: %s", nsg.securityrule)
    }
}

// basically copied from here https://github.com/hashicorp/hcl/blob/v2.16.2/hclsimple/hclsimple.go#l59
// but modified to handle .tf files too
func mydecode(filename string, src []byte, ctx *hcl.evalcontext, target interface{}) error {
    var file *hcl.file
    var diags hcl.diagnostics

    switch suffix := strings.tolower(filepath.ext(filename)); suffix {
    case ".tf":
        file, diags = hclsyntax.parseconfig(src, filename, hcl.pos{line: 1, column: 1})
    case ".hcl":
        file, diags = hclsyntax.parseconfig(src, filename, hcl.pos{line: 1, column: 1})
    case ".json":
        file, diags = json.parse(src, filename)
    default:
        diags = diags.append(&hcl.diagnostic{
            severity: hcl.diagerror,
            summary:  "unsupported file format",
            detail:   fmt.sprintf("cannot read from %s: unrecognized file format suffix %q.", filename, suffix),
        })
        return diags
    }
    if diags.haserrors() {
        return diags
    }

    diags = gohcl.decodebody(file.body, ctx, target)
    if diags.haserrors() {
        return diags
    }
    return nil
}

// taken from here https://github.com/hashicorp/hcl/blob/v2.16.2/hclsimple/hclsimple.go#l89
func mydecodefile(filename string, ctx *hcl.evalcontext, target interface{}) error {
    src, err := ioutil.readfile(filename)
    if err != nil {
        if os.isnotexist(err) {
            return hcl.diagnostics{
                {
                    severity: hcl.diagerror,
                    summary:  "configuration file not found",
                    detail:   fmt.sprintf("the configuration file %s does not exist.", filename),
                },
            }
        }
        return hcl.diagnostics{
            {
                severity: hcl.diagerror,
                summary:  "failed to read configuration",
                detail:   fmt.sprintf("can't read %s: %s.", filename, err),
            },
        }
    }
    return mydecode(filename, src, ctx, target)
}

Wenn ich den Code ausführe, versuche ich im Wesentlichen, networksecuritygroup.securityrule zu definieren, und erhalte mit dem obigen Code die folgende Fehlermeldung:

2023/05/24 11:42:11 Failed to load configuration: nsg.tf:6,3-16: Unsupported argument; An argument named "security_rule" is not expected here. Did you mean to define a block of type "security_rule"?
exit status 1

Alle Vorschläge

Problemumgehungen

sind sehr willkommen, daher ist https://www.php.cn/link/f56de5ef149cf0aedcc8f4797031e229 nicht möglich (siehe hier https://www.php.cn/link/ f56de5ef149cf0aedcc8f47970 31e229/Ausgaben /50 – dieser Vorschlaghclwrite selbst muss der Einfachheit halber geändert werden)

Also habe ich es gelöst, wie @martin atkins vorgeschlagen hat:

Ich habe eine locals.tf-Datei erstellt, die die Variable locals enthält, auf die ich dann in der NSG-Sicherheitsregel verwiesen habe:

locals {
    my_ip = "1.2.3.4"
}

Jetzt hole ich mir einfach meine IP und aktualisiere den Wert in der Datei locals.tf mit sed

my_ip=$(curl -s -4 icanhazip.com)
sed -i "s|my_ip = \".*\"|my_ip = \"$my_ip\"|" locals.tf

Das obige ist der detaillierte Inhalt vonWie kann ich ein Golang-Skript Werte in einer Terraform-Datei (HCL-Format) ändern lassen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen