L'éditeur php Youzi vous apprend à utiliser le script Golang pour modifier la valeur dans le fichier Terraform (format HCL). Terraform est un outil d'infrastructure en tant que code qui nous aide à gérer et automatiser l'infrastructure cloud. Cependant, si l'on doit modifier fréquemment certaines valeurs dans le fichier Terraform, les opérations manuelles deviendront très fastidieuses. Par conséquent, utiliser des scripts Golang pour modifier les valeurs dans les fichiers Terraform sera une méthode plus efficace. Dans cet article, je vais vous montrer comment écrire un script en utilisant Golang pour atteindre cet objectif, afin que vous puissiez facilement modifier les valeurs dans le fichier Terraform.
J'essaie de faire une petite quantité d'automatisation sur un fichier Terraform que j'ai et qui définit un groupe de sécurité réseau Azure. Essentiellement, j'ai un site Web et un accès ssh, je veux uniquement autoriser mon adresse IP publique, à laquelle je peux accéder à partir de la valeur icanhazip.com
获取该地址。我希望使用 golang 脚本将我的 ip 写入 .tf 文件的相关部分(本质上是设置 security_rule.source_address_prefixes
).
J'essaie d'utiliser hclsimple
库,并尝试了 gohcl
、hclwrite
etc en golang mais essentiellement je ne fais aucun progrès dans la conversion des fichiers hcl en structures golang.
Mon fichier Terraform (au format hcl je crois) ressemble à ceci :
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 = [] } ] }
C'est ce que j'ai obtenu avec mon script golang en essayant de représenter les données ci-dessus sous forme de structure, puis de décoder le fichier .tf lui-même (j'ai copié quelques méthodes localement depuis hclsimple
afin qu'il décode le .tf comme suggéré dans son documentation Documents
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) }
Lorsque j'exécute le code, j'essaie essentiellement de définir networksecuritygroup.securityrule et je reçois l'erreur suivante en utilisant le code ci-dessus :
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
Toutes les suggestions sont grandement appréciées
Donc actuellement https://www.php.cn/link/f56de5ef149cf0aedcc8f4797031e229 n'est pas possible (voir ici https://www.php.cn/link/ f56de5ef149cf0aedcc8f47970 31e229/numéros /50 - Cette suggestionhclwrite
elle-même doit être modifiée pour plus de commodité)
Je l'ai donc résolu comme @martin atkins l'a suggéré :
J'ai créé un fichier locals.tf
contenant la variable locals, que j'ai ensuite référencé dans la règle de sécurité nsg :
locals { my_ip = "1.2.3.4" }
Maintenant, je récupère simplement mon adresse IP et mets à jour la valeur dans le fichier locals.tf en utilisant sed
my_ip=$(curl -s -4 icanhazip.com) sed -i "s|my_ip = \".*\"|my_ip = \"$my_ip\"|" locals.tf
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!