Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah saya boleh meminta skrip Golang mengubah suai nilai dalam fail Terraform (format HCL)?

Bagaimanakah saya boleh meminta skrip Golang mengubah suai nilai dalam fail Terraform (format HCL)?

WBOY
WBOYke hadapan
2024-02-09 12:06:28863semak imbas

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

editor php Youzi mengajar anda cara menggunakan skrip Golang untuk mengubah suai nilai dalam fail Terraform (format HCL). Terraform ialah alat infrastruktur sebagai kod yang membantu kami mengurus dan mengautomasikan infrastruktur awan. Walau bagaimanapun, jika kita perlu kerap mengubah suai nilai tertentu dalam fail Terraform, operasi manual akan menjadi sangat membosankan. Oleh itu, menggunakan skrip Golang untuk mengubah suai nilai dalam fail Terraform akan menjadi kaedah yang lebih cekap. Dalam artikel ini, saya akan menunjukkan kepada anda cara menulis skrip menggunakan Golang untuk mencapai ini, supaya anda boleh mengubah suai nilai dengan mudah dalam fail Terraform.

Kandungan soalan

Saya cuba melakukan sedikit automasi pada fail terraform yang saya ada yang mentakrifkan kumpulan keselamatan rangkaian biru. Pada asasnya, saya mempunyai laman web dan akses ssh, saya hanya mahu membenarkan alamat ip awam saya, yang boleh saya akses daripada nilai icanhazip.com 获取该地址。我希望使用 golang 脚本将我的 ip 写入 .tf 文件的相关部分(本质上是设置 security_rule.source_address_prefixes).

Saya cuba menggunakan hclsimple 库,并尝试了 gohclhclwrite dan lain-lain dalam golang tetapi pada asasnya saya tidak membuat sebarang kemajuan dalam menukar fail hcl kepada struktur golang.

Fail terraform saya (dalam format hcl saya percaya) kelihatan seperti ini:

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                         = []
            }
        ]
}

Inilah yang saya dapat dengan skrip golang saya yang cuba mewakili data di atas sebagai struktur dan kemudian menyahkod fail .tf itu sendiri (saya menyalin beberapa kaedah secara setempat daripada hclsimple agar ia menyahkod .tf seperti yang dicadangkan dalam dokumentasinya Dokumen

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)
}

Apabila saya menjalankan kod, pada asasnya saya cuba mentakrifkan networksecuritygroup.securityrule, dan menerima ralat berikut menggunakan kod di atas:

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

Sebarang cadangan amat kami hargai

penyelesaian

Oleh itu, buat masa ini https://www.php.cn/link/f56de5ef149cf0aedcc8f4797031e229 tidak boleh dilakukan (lihat di sini/9fc5f https://www.php cc8f4797031e229/ isu/50 - Cadangan ini sendiri perlu diubah untuk kemudahan)hclwrite

Jadi saya menyelesaikannya seperti yang dicadangkan @martin atkins:

Saya mencipta fail

yang mengandungi pembolehubah tempatan, yang kemudian saya rujuk dalam peraturan keselamatan nsg: locals.tf

locals {
    my_ip = "1.2.3.4"
}

Kini saya hanya mendapat ip saya dan mengemas kini nilai dalam fail locals.tf menggunakan sed

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

Atas ialah kandungan terperinci Bagaimanakah saya boleh meminta skrip Golang mengubah suai nilai dalam fail Terraform (format HCL)?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam