国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Terraform 系列-使用 for-each 對本地 json 進行迭代

這篇具有很好參考價值的文章主要介紹了Terraform 系列-使用 for-each 對本地 json 進行迭代。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

系列文章

  • Terraform 系列文章
  • Grafana 系列文章

概述

前文 Grafana 系列 - Grafana Terraform Provider 基礎(chǔ) 介紹了使用 Grafana Terraform Provider 創(chuàng)建 Datasource.

現(xiàn)在有這么一個現(xiàn)實需求:

有大量的同類型 (type) 的 datasource 需要批量添加,而且這些 datasource 的基本信息是以 json 的格式已經(jīng)存在。

需要對 json 進行解析/精簡/重構(gòu)等操作并將 json 作為 Terraform 的 datasource.

Json 的格式可能類似于這樣:

[
    {
        "env_name": "dev",
        "prom_url": "http://dev-prom.example.com",
        "es_url": "http://dev-es.example.com:9200",
        "jaeger_url": "http://dev-jaeger.example.com"
    },
    {
        "env_name": "test",
        "prom_url": "http://test-prom.example.com",
        "es_url": "http://test-es.example.com:9200",
        "jaeger_url": "http://test-jaeger.example.com"
    }
]

??Notes:

舉一反三,后面的解決方案也適用于其他任意 Json 格式。

該如何實現(xiàn)???

解決方案

通過 Terraform 的 locals jsondecode for 循環(huán) 和 for_each 實現(xiàn)。

具體如下:

  • 構(gòu)造一個 local 變量
  • local 變量從 .json 文件中讀取并內(nèi)容并通過 jsondecode + file 將 json 文件解碼為 object
  • 使用 for 循環(huán),將 object 根據(jù)當前需求調(diào)整,將例子中 env_name 作為 key, 將其他作為 value
  • 批量創(chuàng)建資源時,通過 for_each, 進行批量創(chuàng)建。

基本概念

locals

locals 為 表達式 指定一個名稱,所以你可以在一個模塊中多次使用這個名稱,而不用重復表達式。

如果你熟悉傳統(tǒng)的編程語言,把 Terraform 模塊比作函數(shù)定義可能會很有用:

  • variables(輸入變量) 就像函數(shù)的參數(shù)。
  • outputs(輸出值) 就像函數(shù)的返回值。
  • locals 就像一個函數(shù)的臨時本地變量(局部值)。

一旦聲明了一個本地值,你可以在 表達式 中以local.<NAME>的形式引用它。

本地值有助于避免在配置中多次重復相同的值或表達式,只有在一個單一的值或結(jié)果被用于許多地方的情況下,才可以適度地使用本地值。能夠在一個中心位置輕松地改變數(shù)值是本地值的關(guān)鍵優(yōu)勢。

file 函數(shù)

file讀取指定路徑下的文件內(nèi)容,并將其作為 string 返回。

> file("${path.module}/hello.txt")
Hello World

jsondecode 函數(shù)

jsondecode將一個給定的 string 解釋為 JSON,返回該字符串的解碼結(jié)果。

該函數(shù)以如下方式將 JSON 值映射到 Terraform 語言 type:

JSON type Terraform type
String string
Number number
Boolean bool
Object object(...)的屬性類型根據(jù)此表確定
Array tuple(...)的元素類型根據(jù)此表確定
Null Terraform 語言的 null

Terraform 語言的自動類型轉(zhuǎn)換規(guī)則意味著你通常不需要擔心一個給定的值到底會產(chǎn)生什么類型,只需以直觀的方式使用結(jié)果即可。

> jsondecode("{\"hello\": \"world\"}")
{
  "hello" = "world"
}
> jsondecode("true")
true

jsonencode 執(zhí)行相反的操作,將一個 string 編碼為 JSON。

for 表達式

一個for表達式通過轉(zhuǎn)換另一個復雜類型的值來創(chuàng)建一個復雜類型的值。輸入值中的每個元素可以對應于結(jié)果中的一個或零個值,并且可以使用一個任意的表達式來將每個輸入元素轉(zhuǎn)化為輸出元素。

例如,如果var.list是一個字符串的列表,那么下面的表達式將產(chǎn)生一個全大寫字母的字符串的元組:

[for s in var.list : upper(s)]

這個for表達式遍歷了var.list中的每個元素,然后評估表達式upper(s),將s設(shè)置為每個相應的元素。然后它用所有執(zhí)行該表達式的結(jié)果按相同的順序建立一個新的元組值。

一個for表達式的輸入(在in關(guān)鍵字之后給出)可以是一個列表,一個集合,一個元組,一個 map,或者一個對象 (object)。

上面的例子顯示了一個只有一個臨時符號sfor表達式,但是一個for表達式可以選擇聲明一對臨時符號,以便也使用每個項目的鍵或索引:

[for k, v in var.map : length(k) + length(v)]

對于 map 或?qū)ο箢愋?,像上面那樣?code>k符號是指當前元素的鍵或?qū)傩悦Q。你也可以對列表和 map 使用雙符號形式,在這種情況下,額外的符號是每個元素的索引,從 0 開始,常規(guī)的符號名稱是iidx,除非選擇一個很有幫助的更具體的名稱:

[for i, v in var.list : "${i} is ${v}"]

索引或關(guān)鍵符號總是可選的。如果你在for關(guān)鍵字后面只指定一個符號,那么這個符號將總是代表輸入集合的每個元素的值。

for表達式周圍的括號的類型決定了它產(chǎn)生的結(jié)果的類型。

上面的例子使用[],產(chǎn)生一個元組。如果你用{}代替,結(jié)果是一個對象,你必須提供兩個結(jié)果表達式,用=>符號分開:

{for s in var.list : s => upper(s)}

這個表達式產(chǎn)生一個對象,其屬性是來自var.list的原始元素,其相應的值是大寫版本。例如,產(chǎn)生的值可能如下:

{
  foo = "FOO"
  bar = "BAR"
  baz = "BAZ"
}

單獨的for表達式只能產(chǎn)生一個對象值或一個元組值,但 Terraform 的自動類型轉(zhuǎn)換規(guī)則意味著你通??梢栽谄谕褂昧斜?、map 和集合 (set) 的地方使用其結(jié)果。

一個 for 表達式也可以包括一個可選的 if 子句來過濾源集合中的元素,產(chǎn)生一個比源值更少元素的值:

[for s in var.list : upper(s) if s != ""]

for表達式中過濾集合的一個常見原因是根據(jù)一些標準將一個源集合分成兩個獨立的集合。例如,如果輸入的var.users是一個對象的映射,其中每個對象都有一個屬性is_admin,那么你可能希望產(chǎn)生包含管理員和非管理員對象的單獨映射:

variable "users" {
  type = map(object({
    is_admin = bool
  }))
}

locals {
  admin_users = {
    for name, user in var.users : name => user
    if user.is_admin
  }
  regular_users = {
    for name, user in var.users : name => user
    if !user.is_admin
  }
}

因為for表達式可以從無序類型(map、對象、集合 set)轉(zhuǎn)換為有序類型(列表、元祖),Terraform 必須為無序集合的元素選擇一個隱含的排序。

對于 map 和對象,Terraform 通過鍵或?qū)傩悦Q對元素進行排序,使用詞法排序。

對于字符串的集合,Terraform 按其值排序,使用詞法排序。

for表達式機制是為了在表達式中從其他集合值中構(gòu)建集合值,然后你可以將其分配給期待復雜值的單個資源參數(shù)。

for_each 元參數(shù)

默認情況下,一個 資源塊 配置一個真實的基礎(chǔ)設(shè)施對象(同樣,一個 模塊塊 將一個子模塊的內(nèi)容納入一次配置)。然而,有時你想管理幾個類似的對象(比如一個固定的計算實例池),而不需要為每個對象單獨寫一個塊。Terraform 有兩種方法可以做到這一點: countfor_each

如果一個資源或模塊塊包括一個for_each參數(shù),其值是一個 map 或字符串集合,Terraform 為該 map 或字符串集合的每個成員創(chuàng)建一個實例。

版本說明: for_each是在 Terraform 0.12.6 中添加的。Terraform 0.13 中增加了對for_each 的模塊支持;以前的版本只能在資源中使用它。

注意:一個特定的資源或模塊塊不能同時使用countfor_each。

for_each是 Terraform 語言定義的一個元參數(shù)。它可以與模塊和每一種資源類型一起使用。

for_each 元參數(shù)接受一個 map 或字符串集合,并為該 map 或字符串集合的每個項目創(chuàng)建一個實例。每個實例都有一個獨特的基礎(chǔ)設(shè)施對象與之相關(guān)聯(lián),每個實例都在應用配置時被單獨創(chuàng)建、更新或銷毀。

Map:

resource "azurerm_resource_group" "rg" {
  for_each = {
    a_group = "eastus"
    another_group = "westus2"
  }
  name     = each.key
  location = each.value
}

字符串集合:

resource "aws_iam_user" "the-accounts" {
  for_each = toset( ["Todd", "James", "Alice", "Dottie"] )
  name     = each.key
}

在設(shè)置了for_each 的區(qū)塊中,表達式中還有一個each對象,所以你可以修改每個實例的配置。這個對象有兩個屬性:

  • each.key - 這個實例對應的 map 鍵(或集合成員)。
  • each.value - 該實例對應的 map 值。(如果提供了一個集合,這與each.key相同。)

for_each 被設(shè)置時,Terraform 區(qū)分了區(qū)塊本身和與之相關(guān)的多個資源或模塊實例。實例由提供給for_each的值中的一個 map 鍵(或集合成員)來識別。

  • <TYPE>.<NAME>module.<NAME> (例如,azurerm_resource_group.rg) 代表這個塊。
  • <TYPE>.<NAME>[<KEY>]module.<NAME>[<KEY>] (例如,azurerm_resource_group.rg["a_group"], azurerm_resource_group.rg["another_group"], etc.) 代表獨立的實例

這與沒有countfor_each的資源和模塊不同,它們可以在沒有索引或鍵的情況下被引用。

String & Template

字符串是 Terraform 中最復雜的一種文字表達,也是最常用的一種。

Terraform 同時支持字符串的引號語法和 heredoc 語法。這兩種語法都支持用于插值和操作文本的模板序列。

帶引號的字符串是一系列由雙引號字符(")劃定的字符。

有兩個不使用反斜線的特殊轉(zhuǎn)義序列:

Sequence Replacement
$${ 字面意思是${,不會開始一個插值序列。
%%{ 字面意思是%{,不會開始一個模板指令序列。

${ ... }序列是一個插值,它評估標記之間給出的表達式,如果有必要,將結(jié)果轉(zhuǎn)換為字符串,然后將其插入到最終的字符串中:

"Hello, ${var.name}!"

在上面的例子中,命名的對象var.name被訪問,其值被插入到字符串中,產(chǎn)生的結(jié)果類似 "Hello, Juan!"。

%{ ... } 序列是一個指令,它允許有條件的結(jié)果和對集合的迭代,類似于條件和for表達式。

以下指令被支持:

  • %{if <BOOL>}/%{else}/%{endif}指令根據(jù)一個 bool 表達式的值在兩個模板之間進行選擇:

    "Hello, %{ if var.name != "" }${var.name}%{ else }unnamed%{ endif }!"
    

    else部分可以省略,在這種情況下,如果條件表達式返回false,結(jié)果就是一個空字符串。

  • %{for <NAME> in <COLLECTION>}/%{endfor}指令在給定的集合或結(jié)構(gòu)值的元素上進行迭代,對每個元素評估一次給定的模板,將結(jié)果串聯(lián)起來:

    <<EOT
    %{ for ip in aws_instance.example.*.private_ip }
    server ${ip}
    %{ endfor }
    EOT
    

實戰(zhàn)

需求:

有大量的同類型 (type) 的 datasource 需要批量添加,而且這些 datasource 的基本信息是以 json 的格式已經(jīng)存在。

需要對 json 進行解析/精簡/重構(gòu)等操作并將 json 作為 Terraform 的 datasource.

Json 的格式可能類似于這樣:

[
    {
        "env_name": "dev",
        "prom_url": "http://dev-prom.example.com",
        "es_url": "http://dev-es.example.com:9200",
        "jaeger_url": "http://dev-jaeger.example.com"
    },
    {
        "env_name": "test",
        "prom_url": "http://test-prom.example.com",
        "es_url": "http://test-es.example.com:9200",
        "jaeger_url": "http://test-jaeger.example.com"
    }
]

解決方案

  • 構(gòu)造一個 local 變量
  • local 變量從 .json 文件中讀取并內(nèi)容并通過 jsondecode + file 將 json 文件解碼為 object
  • 使用 for 循環(huán),將 object 根據(jù)當前需求調(diào)整,將例子中 env 作為 key, 將其他作為 value
  • 批量創(chuàng)建資源時,通過 for_each, 進行批量創(chuàng)建。

串起來, 最終如下:

locals {
  # 將 json 文件轉(zhuǎn)換為 對象  
  user_data = jsondecode(file("${path.module}/env-details.json"))
  # 構(gòu)造一個 map
  # key 是 env_name
  # value 又是一個 map, 其 key 是 grafana datasource type, value 是 url
  envs = { for env in local.user_data : env.env_name =>
    {
      prometheus = env.prom_url
      # 利用 ${} 構(gòu)造新的 url
      jaeger     = "${env.jaeger_url}/trace/"
      es         = env.es_url
    }
  }
}

resource "grafana_data_source" "prometheus" {
  # 通過 for_each 迭代
  for_each = local.envs

  type = "prometheus"
  name = "${each.key}_prom"
  uid  = "${each.key}_prom"
  url  = each.value.prometheus

  json_data_encoded = jsonencode({
    httpMethod = "POST"
  })
}

resource "grafana_data_source" "jaeger" {
  for_each = local.envs

  type = "jaeger"
  name = "${each.key}_jaeger"
  uid  = "${each.key}_jaeger"
  url  = each.value.jaeger
}

resource "grafana_data_source" "elasticsearch" {
  for_each = local.envs

  type          = "elasticsearch"
  name          = "${each.key}_es"
  uid           = "${each.key}_es"
  url           = each.value.es
  database_name = "[example.*-]YYYY.MM.DD"

  json_data_encoded = jsonencode({
    esVersion = "6.0.0"

    interval = "Daily"
    includeFrozen              = false
    maxConcurrentShardRequests = 256
    timeField                  = "@timestamp"

    logLevelField   = "level"
    logMessageField = "message"
  })
}

完成??????

???參考文檔

  • Overview - Configuration Language | Terraform | HashiCorp Developer
  • Terraform: Using for-each in Terraform to iterate through local JSON (copyprogramming.com)
  • automation - Iterate over Json using Terraform - Stack Overflow
  • Using data returned by jsondecode and iterate over the results in a for_each loop - Terraform - HashiCorp Discuss
  • How to Use Terraform's 'for_each', with Examples - The New Stack

三人行, 必有我?guī)? 知識共享, 天下為公. 本文由東風微鳴技術(shù)博客 EWhisper.cn 編寫.文章來源地址http://www.zghlxwxcb.cn/news/detail-499220.html

到了這里,關(guān)于Terraform 系列-使用 for-each 對本地 json 進行迭代的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • springboot對本地文件進行操作

    方案一:使用ResourceUtils 這種方案是一個坑,詳細內(nèi)容參考:springboot讀寫磁盤json格式文件 使用這種方案一般都會提示: java.io.FileNotFoundException 方案二:使用commons-io commons-io中提供了文件的常規(guī)讀、寫工具類 讀寫文件時需要傳入文件所在磁盤路徑 參考如下代碼 上面方法存在

    2023年04月25日
    瀏覽(9)
  • list_for_each_entry詳解

    參考鏈接: 終于理解list_entry和list_for_each_entry linux 內(nèi)核代碼中l(wèi)ist_for_each_entry宏之我見 linux之list_for_each和list_for_each_entry函數(shù) container_of的用法 用戶態(tài)下的list.h Linux內(nèi)核中的許多鏈表操作,都是使用list_for_each_entry進行遍歷,其定義在/usr/src/linux-2.6.32.9/include/linux/list.h路徑,具體

    2024年02月15日
    瀏覽(17)
  • Terraform 系列-Terraform 簡介

    ?? Terraform 系列文章 最近在使用 Terraform 來置備 OCI 的 Always Free Tier, 發(fā)現(xiàn)它非常好用??偨Y(jié)學習下:Terraform 的基礎(chǔ)知識。 Terraform 是一種 基礎(chǔ)架構(gòu)即代碼(IaC) 工具,可讓您安全高效地構(gòu)建、更改云和本地資源并對其進行 版本控制 。 HashiCorp Terraform 是一種基礎(chǔ)架構(gòu)即代碼工具

    2023年04月12日
    瀏覽(24)
  • Yolov5對本地視頻進行推理時,實現(xiàn)跳幀檢測,提高推理效率

    Yolov5對本地視頻進行推理時,實現(xiàn)跳幀檢測,提高推理效率

    今天在使用Yolov5的detect.py對本地視頻進行推理時,發(fā)現(xiàn)推理速度受硬件性能影響比較大,為提高檢測效率,在部分沒必要逐幀檢測的情況下,可以考慮設(shè)置跳幀檢測。 對detect.py觀察了一番之后,發(fā)現(xiàn)視頻讀取靠的是dataloaders.py庫,于是繼續(xù)觀察。 最終得出了以下解決方案:

    2024年02月12日
    瀏覽(42)
  • Terraform 系列-Terraform Cloud 比 Terraform OSS 有哪些增強?

    Terraform 系列-Terraform Cloud 比 Terraform OSS 有哪些增強?

    ?? Terraform 系列文章 最近在使用 Terraform Cloud 來置備 OCI 的 Always Free Tier, 發(fā)現(xiàn)它非常好用,相比 Terraform OSS, 用起來省心多了。 也借此總結(jié)學習下:Terraform Cloud 比 Terraform OSS 有哪些增強,這些增強功能面向哪些客戶,解決了哪些痛點? 可以作為我們基于 Terraform 開發(fā)自己的

    2023年04月13日
    瀏覽(22)
  • 「SQL面試題庫」 No_123 The Most Recent Orders for Each Product

    「SQL面試題庫」是由 不是西紅柿 發(fā)起,全員免費參與的SQL學習活動。我每天發(fā)布1道SQL面試真題,從簡單到困難,涵蓋所有SQL知識點,我敢保證只要做完這100道題,不僅能輕松搞定面試,代碼能力和工作效率也會有明顯提升。 1.1 活動流程 整理題目 :西紅柿每天無論刮風下雨

    2024年02月15日
    瀏覽(39)
  • Terraform 系列-什么是 IaC?

    ?? Terraform 系列文章 聊到 Terraform, 必然繞不開 IaC 這個概念?那么,什么是 IaC? ?? 基礎(chǔ)架構(gòu)即代碼 (Infrastructure as Code, IaC) 是指通過 代碼 而不是手動流程/控制臺點擊來管理和配置基礎(chǔ)架構(gòu)。 這里有 2 個: Infrastructure Code Infrastructure 是被管理對象,在這里,主要是指公

    2023年04月11日
    瀏覽(19)
  • Terraform 系列-批量創(chuàng)建資源時如何根據(jù)某個字段判斷是否創(chuàng)建

    Terraform 系列文章 Grafana 系列文章 前文 Grafana 系列 - Grafana Terraform Provider 基礎(chǔ) 介紹了使用 Grafana Terraform Provider 創(chuàng)建 Datasource. 這幾天碰到這么一個現(xiàn)實需求: 使用 Terraform 批量創(chuàng)建日志數(shù)據(jù)源時, 有的數(shù)據(jù)源類型是 ElasticSearch, 有些是 Opensearch. 那么, 如何根據(jù)某個字段(如: es_t

    2024年02月13日
    瀏覽(98)
  • 【C++】STL 算法 ③ ( 函數(shù)對象中存儲狀態(tài) | 函數(shù)對象作為參數(shù)傳遞時值傳遞問題 | for_each 算法的 函數(shù)對象 參數(shù)是值傳遞 )

    【C++】STL 算法 ③ ( 函數(shù)對象中存儲狀態(tài) | 函數(shù)對象作為參數(shù)傳遞時值傳遞問題 | for_each 算法的 函數(shù)對象 參數(shù)是值傳遞 )

    在 C++ 語言中 , 函數(shù)對象 / 仿函數(shù) 可以像函數(shù)一樣被調(diào)用 , 并且 其 還具有類的特征 , 可以 通過 繼承 和 重載 來 修改 重載函數(shù)調(diào)用操作符函數(shù) 的行為 ; 函數(shù)對象 / 仿函數(shù) 通常是通過 定義一個類 , 然后為這個類 重載 函數(shù)調(diào)用操作符 () 來實現(xiàn)的 ; 函數(shù)對象的一個重要特性是

    2024年02月02日
    瀏覽(22)
  • 【使用內(nèi)網(wǎng)穿透從公網(wǎng)對本地內(nèi)網(wǎng)Web服務(wù)器訪問】

    【使用內(nèi)網(wǎng)穿透從公網(wǎng)對本地內(nèi)網(wǎng)Web服務(wù)器訪問】

    隨著科技進步和時代發(fā)展,計算機及互聯(lián)網(wǎng)已經(jīng)深深融入我們的生活和工作,與之對應的,對計算機及網(wǎng)絡(luò)的探索,讓其為我們的生活增添色彩和樂趣,也成為很多人的業(yè)余愛好,而自行發(fā)布一個網(wǎng)站,就是這一愛好的直接體現(xiàn)。在現(xiàn)代眾多軟件的幫助下,我們已經(jīng)可以在本

    2024年02月14日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包