Skip to main content

moregeek program

[译]terraform – external data source-多极客编程

前言

简而言之,外部数据源(不是特别推荐!) 意味着试图从外部数据源获取一些信息并将其呈现给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 terraform
declare -A test_var
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 input
eval "$(jq -r '@sh "p_env=\(.p_env)"')"
# Step#2 - Extract the ip address and port number based on the key passed
url_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 back
jq -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: yes

Apply 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 sys
import json
# Magical list of ip addresses and ports which cannot exist in terraform
test_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 input
input = sys.stdin.read()
input_json = json.loads(input)
# Step#2 - Extract the ip address and port number based on the key passed
arr = 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: yes

Apply 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​

©著作权归作者所有:来自51CTO博客作者suzfdotnet的原创作品,请联系作者获取转载授权,否则将追究法律责任

how-to centralized integration of eventbridge event notifications sent to feishu-多极客编程

简介在使用亚马逊云的过程中,各种服务的通知事件在日常运维里常常发挥着关键作用。但在实际使用过程中,这些通知常常因为各种原因被忽略而导致意外的损失。如:亚马逊云的维护事件会发送通知邮件到账号的注册邮箱,但这些邮箱通常无人值守,使得在维护事件发生时,客户会遭遇“意外”停机。另外,客户部署的工作负载也有各种自定义的通知希望集成到一个统一的客户端进行提醒;而现在各种流行的即时通信软件都有移动客户端,同时基

48-docker-多容器数据共享及持久化-多极客编程

Docker镜像数据读写原理Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW copyon write)"机制COW机制节约空间,但会导致性低下,虽然关闭重启容器

pod管理-多极客编程

Pod调度基于节点调度---kind: PodapiVersion: v1metadata: name: myhttpdspec: terminationGracePeriodSeconds: 0 restartPolicy: Always nodeName: node-0001 # 基于节点名称进行调度 containers: - name: apache image: m

选择 k3s 还是 rke3?一文读懂!-多极客编程

K3s 和 RKE2 是 SUSE Rancher 容器平台的两个 Kubernetes 发行版,都可以运行生产就绪的集群,但是它们适用的用例不同,两者都有独特的功能。本文将介绍这两个项目的相同点和差异性,帮您了解如何合理选用 RKE2 和 K3s,来满足容器化工作负载的安全性和合规性。K3s 和 RKE2K3s 仅使用一个不到 70MB 的二进制文件来提供生产就绪的 Kubernetes 集群。

how-to centralized integration of eventbridge event notifications sent to feishu-多极客编程

简介在使用亚马逊云的过程中,各种服务的通知事件在日常运维里常常发挥着关键作用。但在实际使用过程中,这些通知常常因为各种原因被忽略而导致意外的损失。如:亚马逊云的维护事件会发送通知邮件到账号的注册邮箱,但这些邮箱通常无人值守,使得在维护事件发生时,客户会遭遇“意外”停机。另外,客户部署的工作负载也有各种自定义的通知希望集成到一个统一的客户端进行提醒;而现在各种流行的即时通信软件都有移动客户端,同时基

异构操作系统的“融合计算”-多极客编程

近些年,由随着应用场景日益丰富和多样化,计算工作越来越复杂,传统的计算方式(单机计算/分布式计算)已经不能满足,需要一种新的更强大的计算模式来解决这些问题,这是融合计算产生的背景。​融合计算涉及两个层面:操作系统和应用场景,先说操作系统。​目前的操作系统,都有自己的产品定位和应用边界。比如Windows对标的是个人电脑,通常处理个人编辑类业务。iOS和安卓因为移动性强,多用于社交娱乐方面的交互工作

kubernetes 部署 harbor-多极客编程

helm 部署项目地址​​Releases · helm/helm (github.com)​​安装流程[root@k8s-master2 ~]# mkdir helm[root@k8s-master2 ~]# cd helmtar zxvf helm-v3.5.4-linux-amd64.tar.gz cp -av linux-amd64//helm /usr/local/bin/helm h