[譯]Terraform – External Data Source

2023-01-11 15:18:58 來源:51CTO博客

前言

簡而言之,外部數據源(不是特別推薦!) 意味著試圖從外部數據源獲取一些信息并將其呈現給Terraform。Terraform外部數據源執行shell腳本或python或任何其他程序。Terraform像使用其他數據源一樣使用程序的輸出。這意味著外部數據源為Terraform提供了一種與外部世界交互的方式。這是非常有用的!

注意: 外部數據源與AWS、Azure或谷歌云提供商或任何其他云提供商無關。

外部數據源基本介紹

如上所述的外部數據源允許Terraform與外部環境進行數據交互。那么這里的捕獲信息是什么(這里總是有一個捕獲信息),程序的輸入和輸出必須是JSON對象。要通過shell腳本使用Terraform外部數據源,您最好了解 jq。


(相關資料圖)

注意:外部數據源允許Terraform與外部環境進行交互。敲黑板,所有必需的軟件都要事先安裝好,否則以后可能會出現令人討厭的意外。只有當你在Terraform 中找不到解決方案時才使用它。

一個潛在的用例-我發現這很有用(您可能不同意),當獲取有關AWS(或任何其他云)資源的信息時,Terraform數據資源沒有提供有關該云資源的所有信息。例如,用于Kafka的AWS Managed Service的Terraform數據資源沒有為代理提供子網信息(至少在我寫代碼之前沒有)。盡管這些信息可以通過AWS CLI或boto庫獲得。

這里沒有太多參數可以傳遞給外部數據源,只有兩個!

外部數據源參數

描述

程序

Python 或 shell 的可執行程序

查詢

作為JSON傳遞給程序的變量

注意: 程序被 locally 所執行

最后,這里是我們博客的一個用例,我們想根據傳遞給shell腳本的environment 和url這兩個參數返回ip地址和端口。這些信息在Terraform中是不可用的,因為它總是神奇地變化;)。在我們繼續之前,shell腳本和python的示例幾乎都做同樣的事情,只是為了說明這篇文章的目的。

外部數據源 & shell 腳本

讓我們看看如何通過調用shell腳本獲取terrraform外部數據源。將執行以下步驟

創建一個shell腳本從Terraform外部數據源調用shell腳本向它傳遞一些參數并進行一些處理。處理完成后,腳本將輸出作為JSON對象返回到terraform。

注意: 確保您已經安裝了jq,除非您想手動處理JSON對象,同時安裝您的shell腳本任何其他庫/包。

Terraform 腳本

我們的terrraform腳本ext_data_source.tf是非常簡單的,它調用shell腳本get_ip_port.sh,并傳遞一個參數p_env,它的值是dev。現在,這個值可以是其他任何東西,作為Terraform提供的資源的一部分,它是動態生成的!!

data "external" "get_ip_addres_using_shell_dev" { program = ["bash","scripts/get_ip_port.sh"] query = {   p_env = "dev" }}output "ip_address_for_dev" { value = data.external.get_ip_addres_using_shell_dev.result.ip_address}output "port_num_for_dev" { value = data.external.get_ip_addres_using_shell_dev.result.port_num}

Shell 腳本

#!/bin/bash# Step#0 - Magical list of ip addresses and ports which cannot exist in terraformdeclare -A test_vartest_var["dev"]="10.0.0.1:8081"test_var["qa"]="10.0.0.2:8082"test_var["uat"]="10.0.0.3:8083"test_var["stage"]="10.0.0.4:8084"test_var["prod"]="10.0.0.5:8085"# Step#1 - Parse the inputeval "$(jq -r "@sh "p_env=\(.p_env)"")"# Step#2 - Extract the ip address and port number based on the key passedurl_str=${test_var[$p_env]}arr=(${url_str//:/ })IP_ADDRESS=${arr[0]}PORT_NUM=${arr[1]}# Step#3 - Create a JSON object and pass it backjq -n --arg ip_address "$IP_ADDRESS" \     --arg port_num "$PORT_NUM" \     "{"ip_address":$ip_address, "port_num":$port_num}"

讓我們簡單看一下shell腳本的邏輯

Step#1 – 輸入解析為 JSON,數據被提取到一個名為 p_env 的變量中Step#2 – 變量p_dev用于從hashmap中提取ip地址和端口號Step#3 – 使用 jq 返回包含 ip 地址和端口號的 JSON 對象

讓我們看一下運行terrraform apply 之后的輸出

Do you want to perform these actions? Terraform will perform the actions described above. Only "yes" will be accepted to approve. Enter a value: yesApply complete! Resources: 0 added, 0 changed, 0 destroyed.Outputs:ip_address_for_dev = "10.0.0.1"port_num_for_dev = "8081"

外部數據源 & Python

Terraform 腳本

我們的terrraform腳本ext_data_source.tf非常簡單,它調用Python腳本get_ip_port.py,并傳遞一個值為qa到參數p_env。正如您所看到的,這與前一節中的非常相似。

data "external" "get_ip_addres_using_python" { program = ["python3","scripts/get_ip_port.py"] query = {   p_env = "qa" }}output "ip_address_for_qa" { value = data.external.get_ip_addres_using_python_dev.result.ip_address}output "port_num_for_qa" { value = data.external.get_ip_addres_using_python_dev.result.port_num}

Python Script

import sysimport json# Magical list of ip addresses and ports which cannot exist in terraformtest_var = dict()test_var["dev"]   = "10.0.0.1:8081"test_var["qa"]    = "10.0.0.2:8082"test_var["uat"]   = "10.0.0.3:8083"test_var["stage"] = "10.0.0.4:8084"test_var["prod"]  = "10.0.0.5:8085"# Step#1 - Parse the inputinput = sys.stdin.read()input_json = json.loads(input)# Step#2 - Extract the ip address and port number based on the key passedarr = test_var[input_json.get("p_env")].split(":")ip_address = arr[0]port_num = arr[1]# Step#3 -  Create a JSON object and just print it(i.e send it to stdout)output = {   "ip_address": ip_address,   "port_num": port_num}output_json = json.dumps(output,indent=2)print(output_json)

下面是在python腳本中完成的步驟的概述,這些步驟與前一節中的shell腳本非常相似

Step#1 – 輸入解析Step#2 – 從字典中提取ip地址和端口號Step#3 – 返回包含ip地址和端口號的JSON對象

讓我們看一下運行terrraform apply 之后的輸出

Do you want to perform these actions? Terraform will perform the actions described above. Only "yes" will be accepted to approve. Enter a value: yesApply complete! Resources: 0 added, 0 changed, 0 destroyed.Outputs:ip_address_for_dev = "10.0.0.2"port_num_for_dev = "8082"

從上面可以看出,外部數據源是將Terraform與外部環境連接起來的非常有用的工具。顯然也不難理解。希望你覺得這篇文章有用。如果你喜歡它,請分享它并傳播知識!

源文章?????https://www.cloudwalker.io/2021/10/09/terraform-external-data-source/???

License:??Attribution-NonCommercial-ShareAlike 4.0 International??

本文出自??Suzf Blog??。 如未注明,均為 SUZF.NET 原創。

轉載請注明:??https://suzf.net/post/1459??

標簽: 外部環境

上一篇:How-to centralized integration of eventbridge event notifications sent to feishu
下一篇:當前滾動:C語言指針統覽