使用 cURL 调用 Terraform REST API

sko*_*hrs 8 terraform

从 Terraform 进行 REST API 调用的最佳方法是什么?我目前使用的是null_resourcelocal-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)


moe*_*ius 12

我自己没有使用过它,但这可能对你有用: https: //github.com/Mastercard/terraform-provider-restapi