带你掌握利用Terraform不同数据源扩展应用场景
本文分享自华为云社区《利用Terraform不同数据源扩展应用场景》,作者: kaliarch 。
一 背景
在生产环境中使用Terraform进行基础设施编排,通常又一些信息是通过其他外部系统传入,该场数据源为一个接口,需要Terraform具备调用远程接口能力,获取数据进行目标资源编排,处理各种云厂商提供的provider接口data数据类型外,terraform社区还具备http provider,利用此可以进行调用第三方外部系统接口,实现自助外部接口获取编排。
除了Terraform直接通过调用http provider接口获取数据外,还可以使用执行本地Shell/Python脚本,脚本内部实现调用外部接口获取数据,再将数据进行传入到Terraform进行使用。
二 原理
2.1 数据源概念
数据源允许获取和计算数据,以便在代码中使用。源可以位于另一个Terraform配置中或外部。与资源相反,数据源不由Terraform管理。
2.2 数据源优势
- 减少模块之间的耦合,并使用您的基础设施作为事实的来源。
- 通过减少变量的数量来隐藏Terraform最终用户的复杂性
2.3 扩展数据源方式
2.3.1 http
terraform下载http provider,其内部为一个go编写的http客户端,可以实现调用外部接口。
https://registry.terraform.io/providers/hashicorp/http/latest/docs
2.3.2 脚本方式
terraform扮演执行器,利用external provider进行执行各脚本语言,实现执行脚本内容达到预定目标。
三 http数据源
3.1 测试场景
使用Terraform编写编排文件,获取github个人资料信息。
3.2 代码
- 目录结构
├── main.tf // 主文件 ├── outputs.tf // 输出文件 └── variables.tf // 变量文件
- 代码内容
# main.tf
data "http" "get_method" {
url = "https://api.github.com/users/${var.gitName}"
request_headers = {
Accept = "application/json"
}
}
data "http" "post_method" {
url = "https://checkpoint-api.hashicorp.com/v1/check/terraform"
method = "POST"
# Optional request body
request_body = "request body"
}
# variables.tf
variable "gitName" {
type = string
default = "redhatxl"
}
# outputs.tf
output "resp" {
value = {
get = data.http.get_method.body
post = data.http.post_method.body
}
}
3.3 测试
# init $ terraform init # plan $ terraform plan # 将输出文件到处到json文件中 $ terraform show --json github.out | > redhatxl.json # apply应用 $ terraform apply

3.4 其他
3.4.1 POST请求
data "http" "example_post" {
url = "https://checkpoint-api.hashicorp.com/v1/check/terraform"
method = "POST"
# Optional request body
request_body = "request body"
}
3.4.2 后置条件
data "http" "example" {
url = "https://checkpoint-api.hashicorp.com/v1/check/terraform"
# Optional request headers
request_headers = {
Accept = "application/json"
}
lifecycle {
postcondition {
condition = contains([201, 204], self.status_code)
error_message = "Status code invalid"
}
}
}
3.4.3 前置条件
data "http" "example" {
url = "https://checkpoint-api.hashicorp.com/v1/check/terraform"
# Optional request headers
request_headers = {
Accept = "application/json"
}
}
resource "random_uuid" "example" {
lifecycle {
precondition {
condition = contains([201, 204], data.http.example.status_code)
error_message = "Status code invalid"
}
}
}
3.4.4 使用Provisioner
data "http" "example" {
url = "https://checkpoint-api.hashicorp.com/v1/check/terraform"
# Optional request headers
request_headers = {
Accept = "application/json"
}
}
resource "null_resource" "example" {
# On success, this will attempt to execute the true command in the
# shell environment running terraform.
# On failure, this will attempt to execute the false command in the
# shell environment running terraform.
provisioner "local-exec" {
command = contains([201, 204], data.http.example.status_code)
}
}
四 脚本执行
“外部数据源允许实现特定协议(定义如下)的外部程序充当数据源,公开任意数据以供Terraform配置中的其他地方使用。”
有时,我的terraform模块依赖于不是由terraform提供者管理的数据,而是由我的存储库中的构建步骤或脚本管理的数据。外部数据源是一个接口,用于在运行terraform的机器上本地运行命令,并提供该程序的控制台输出作为数据源。
这是一种允许本地脚本充当数据源的机制。要成为有效的数据源,本地脚本只需将JSON打印为标准输出,如下所示:

4.1 测试场景
使用Terraform编写编排文件,获取github个人资料信息。
4.2 代码
├── main.tf ├── outputs.tf ├── scripts │ └── py │ └── fetch_githubinfo.py └── variables.tf
- main.tf
data "external" "githubinfo" {
program = ["python", "${path.module}/scripts/py/fetch_githubinfo.py"]
query = {
gitName = var.gitName
}
}
locals {
resp = data.external.githubinfo.result
}
- variables.tf
variable "gitName" {
type = string
}
- outputs.tf
output "resp" {
value = {
get = local.resp
}
}
- fetch_githubinfo.py
#!/usr/bin/env python3
# coding: utf-8
import json
from terraform_external_data import terraform_external_data
import requests
import json
@terraform_external_data
def fetch(query):
# Terraform requires the values you return be strings,
# so terraform_external_data will error if they aren't.
gitName = query['gitName']
response = requests.get(f'https://api.github.com/users/{gitName}')
output_json = response.json()
return {str(key): str(value) for key, value in output_json.items()}
if __name__ == "__main__":
fetch()
4.3 测试
执行terraform init/terraform apply

4.4 其他
- terraform扮演执行器,可以执行shell/js/golang/python等各语言代码,但需要在执行环境中具备对应语言的解释器。
五 总结
利用data 的http/external可以非常方便的是心啊调用外部接口获取数据。但官方对于External Data Source的定位是"逃生窗口",因此在考虑使用该方案时,为最后手段。
参考链接
带你掌握利用Terraform不同数据源扩展应用场景的更多相关文章
- WPF 自带Datagrid编辑后无法更新数据源的问题
原文 WPF 自带Datagrid编辑后无法更新数据源的问题 解决办法: 在列的绑定属性里加上UpdateSourceTrigger,示例XAML如下 <DataGrid Grid.Row=& ...
- Azure Terraform(十二)利用 Terraform 将文件上传到 Azure Blob Storage
一,引言 本篇文章中,我门将学习如何利用 Terraform 将 文件以及文件夹上传到 Azure Blob Storage,这个对于我们来说很方便,可以将一些不重要的内容也存储在源代码管理工具中! ...
- 理解钩子Hook以及在Thinkphp下利用钩子使用行为扩展
什么是钩子函数 个人理解:钩子就像一个”陷阱”.”监听器”,当A发送一个消息到B时,当消息还未到达目的地B时,被钩子拦截调出一部分代码做处理,这部分代码也叫钩子函数或者回调函数 参考网上说法 譬如我们 ...
- 利用Delphi编写IE扩展
就是如何使IE扩展组件可以响应事件. 在自己的程序中使用过WebBrowser控件的朋友都知道,WebBrowser控件定义了诸如BeforeNavigate.DownloadComplete ...
- 一分钟带你学会利用mybatis-generator自动生成代码!
目录 一.MyBatis Generator简介 二.使用方式 三.实战 之前的文章<SpringBoot系列-整合Mybatis(XML配置方式)>介绍了XML配置方式整合的过程,本文介 ...
- java分享第十八天-02( java结合testng,利用XML做数据源的数据驱动)
testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本.在这以XML为例:备注:@DataProvider的返回值类 ...
- 利用phpize 外挂php扩展
如果你的php是手动编译安装的 ,可能有一些扩展一开始并没有开启,以后需要某扩展的时候又不想重新编译php,使用phpize可以动态添加扩展 以Ubuntu为例, 如果你是我这样安装php的 apt ...
- C# 利用范型与扩展方法重构代码
在一些C#代码中常常可以看到 //An Simple Example By Ray Linn class CarCollection :ICollection { IList list; public ...
- java结合testng,利用excel做数据源的数据驱动实例
数据驱动部分,是自动化测试常用部分,也是参数化设计的重要环节,前面分享了,mysql.yaml做数据源,那么再来分享下excel做数据驱动 思路: 先用POI读取excel.解析读取数据,返回list ...
- java结合testng,利用yaml做数据源的数据驱动实例
testng的功能很强大,利用@DataProvider可以做数据驱动,数据源文件可以是EXCEL,XML,YAML,甚至可以是TXT文本.在这以yaml为例: 备注:@DataProvider的返回 ...
随机推荐
- ip addr命令解析
转载请注明出处: 1.ip addr命令使用解析 ip addr 命令是Linux系统中的一个网络管理工具,用于显示和配置系统中的网络接口及其地址信息.它可以列出系统中所有的网络接口及其详细信息,包括 ...
- ADB-安装配置
一.只要下载ADB安装包即可 就这4个文件: 备注:如果下载放入到D盘去解压,打开dos窗口那么就要进入到D盘,然后再去执行adb命令,输入adb查看它是否安装成功 二.ADB命令简单使用 查看连接设 ...
- 如何用 KMP 偏序 Z 函数
KMP 算法求解字符串匹配的过程中 \(next\) 数组有着繁多的应用,主要是可以帮我们求 border. 然而用 \(s\) 串匹配 \(t\) 串产生的 \(f\) 数组应用相对较少. \(f\ ...
- AutoCAD二次开发系列教程01-如何在AutoCAD中输出Hello World
目录 01项目环境准备 02代码示例 03输出示例 04总结 05源码地址 01项目环境准备 A.开发使用的软件:AutoCAD2016.VisualStudio2022 B.建立依赖的本地库(提前从 ...
- Prism Sample 24-NavigationJournal
本例是在上一案例中导航参数的基础上增加了导航的历史记录功能,就是向前向后的功能. 导航本身很简单,以下代码就实现了: public void OnNavigatedTo(NavigationConte ...
- 基于机器人自主移动实现SLAM建图
博客地址:https://www.cnblogs.com/zylyehuo/ 基于[移动机器人运动规划及运动仿真],详见之前的博客 移动机器人运动规划及运动仿真 - zylyehuo - 博客园 参考 ...
- 计算机网络 传输层协议TCP和UDP
目录 一.传输层协议 二.tcp协议介绍 三.tcp报文格式 四.tcp三次握手 五.tcp四次挥手 六.udp协议介绍 七.常见协议和端口 八.有限状态机 一.传输层协议 传输层协议主要是TCP和U ...
- WPF入门教程系列二十六——DataGrid使用示例(3)
WPF入门教程系列目录 WPF入门教程系列二--Application介绍 WPF入门教程系列三--Application介绍(续) WPF入门教程系列四--Dispatcher介绍 WPF入门教程系 ...
- UART-UART非常见波特率调试应用笔记
UART非常见波特率调试 应用笔记 串口通信中的波特率选择,对于确保可靠的数据传输至关重要.波特率是衡量单位时间内传输的比特数,常见的波特率包括300.1200.2400.9600.115200等.不 ...
- linux 递归和函数实验
递归 作用:自己调用自己 1.例子:阶乘 2.遍历目录下所有文件 函数 1.函数能够接受一个参数,参数为用户名: 判断一个用户是否存在 如果存在,就返回此用户的shell 和 UID :并返回正常状态 ...