本文介绍了使用 cURL 调用 Terraform REST API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从 Terraform 进行 REST API 调用的最佳方式是什么?我目前正在使用 null_resourcelocal-exec 供应商来进行 cURL 调用:

What is the best way to make REST API calls from Terraform? I'm currently using a null_resource with the local-exec provisioner to make a cURL call:

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
  }

但是,对于 HTTP 200 和 HTTP 400 响应,cURL 返回码是成功的.如果无法注册新帐户,我希望将资源标记为失败.

However, the cURL return code is successful for HTTP 200 and HTTP 400 responses. I'd like the resource to be marked as failed if the new account cannot be registered.

我尝试只返回 HTTP 响应代码:

I've tried returning just the HTTP Response Code:

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
  }

但随后我丢失了 API 响应正文,其中包含有价值的信息.有时 HTTP 400 代码表明该帐户已经存在,从整体设置的角度来看,我认为这是成功的.

But then I lose the API response body, which contains valuable information. There are also times when a HTTP 400 code indicates the account already exists, which I consider a success from the overall setup standpoint.

推荐答案

这个问题已经被浏览了超过 10,000 次,我意识到我从来没有发布我的解决方案.我最终编写了一个 Python 脚本来处理各种 API 响应并控制对 Terraform 的返回代码.

This question has been viewed over 10,000 times and I realized I never posted my solution to the problem. I ended up writing a Python script to handle the various API responses and controlling the return codes to 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"]
}

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())

这篇关于使用 cURL 调用 Terraform REST API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 03:44
查看更多