从 Terraform 进行 REST API 调用的最佳方法是什么?我目前使用的是null_resource
与local-exec
供应方做出卷曲电话:
resource "null_resource" "cloudability-setup" {
provisioner "local-exec" {
command = <<EOT
curl -s -X POST https://api.cloudability.com/v3/vendors/aws/accounts \
-H 'Content-Type: application/json' \
-u "$${CldAbltyAPIToken:?Missing Cloudability API Token Env Variable}:" \
-d '{"vendorAccountId": "${data.aws_caller_identity.current.account_id}", "type": "aws_role" }'
EOT
}
Run Code Online (Sandbox Code Playgroud)
但是,cURL 返回码对于 HTTP 200 和 HTTP 400 响应是成功的。如果无法注册新帐户,我希望将资源标记为失败。
我试过只返回 HTTP 响应代码:
resource "null_resource" "cloudability-setup" {
provisioner "local-exec" {
command = <<EOT
curl -s -o /dev/null -w "%{http_code}" \
-X POST https://api.cloudability.com/v3/vendors/aws/accounts \
-H 'Content-Type: application/json' \
-u "$${CldAbltyAPIToken:?Missing Cloudability API Token Env Variable}:" \
-d '{"vendorAccountId": "${data.aws_caller_identity.current.account_id}", "type": "aws_role" }'
EOT
}
Run Code Online (Sandbox Code Playgroud)
但随后我丢失了包含有价值信息的 API 响应主体。有时,HTTP 400 代码表明帐户已经存在,从整体设置的角度来看,我认为这是成功的。
sko*_*hrs 13
这个问题已被查看超过 10,000 次,我意识到我从未发布过该问题的解决方案。我最终编写了一个 Python 脚本来处理各种 API 响应并控制 Terraform 的返回代码。
地形资源:
resource "null_resource" "cloudability-setup" {
provisioner "local-exec" {
command = "${path.module}/cloudability_setup.py -a ${data.aws_caller_identity.current.account_id} -t aws_role"
}
depends_on = ["aws_iam_role.cloudability-role"]
}
Run Code Online (Sandbox Code Playgroud)
Python脚本:
import getopt
import json
import os
import requests
import sys
def print_help():
print '''
Usage: cloudability_setup.py [options]
cloudability_setup -- Register new account with Cloudability
Options:
-h, --help Show this help message and exit
-a <acct #>, --acctnum=<acct #>
Required argument: IaaS Account Number
-t <type>, --type=<type>
Required argument: IaaS Account Type
'''
def register_acct(acctnum, type):
url = 'https://api.cloudability.com/v3/vendors/aws/accounts'
token = os.environ['CldAbltyAPIToken']
headers = {'Content-Type': 'application/json'}
data = '{"vendorAccountId": "' + acctnum + '", "type": "'+ type + '" }'
response = requests.post(url, auth=(token,''), headers=headers, data=data)
# If new account was registered successfully, update externalID:
if response.status_code == requests.codes.created:
update_acct(acctnum, type)
# If account already exists, update externalID:
elif str(response.status_code) == '409':
update_acct(acctnum, type)
else:
print "Bad response from Cloudability API while registering new account."
print "HTTP: " + str(response.status_code)
sys.exit(3)
def update_acct(acctnum, type):
url = 'https://api.cloudability.com/v3/vendors/aws/accounts/' + acctnum
token = os.environ['CldAbltyAPIToken']
headers = {'Content-Type': 'application/json'}
data = '{"type": "' + type + '", "externalId": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX" }'
response = requests.put(url, auth=(token,''), headers=headers, data=data)
if response.status_code == requests.codes.ok:
sys.exit()
else:
print "Bad response from Cloudability API while updating account."
print "HTTP: " + str(response.status_code)
sys.exit(3)
def main(argv=None):
'''
Main function: work with command line options and send an HTTPS request to the Cloudability API.
'''
try:
opts, args = getopt.getopt(sys.argv[1:], 'ha:t:',
['help', 'acctnum=', 'type='])
except getopt.GetoptError, err:
# Print help information and exit:
print str(err)
print_help()
sys.exit(2)
# Initialize parameters
acctnum = None
type = None
# Parse command line options
for opt, arg in opts:
if opt in ('-h', '--help'):
print_help()
sys.exit()
elif opt in ('-a', '--acctnum'):
acctnum = arg
elif opt in ('-t', '--type'):
type = arg
# Enforce required arguments
if not acctnum or not type:
print_help()
sys.exit(4)
register_acct(acctnum, type)
if __name__ == '__main__':
sys.exit(main())
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12716 次 |
最近记录: |