【问题标题】:Terraform REST API calls with cURL使用 cURL 调用 Terraform REST API
【发布时间】:2021-09-20 16:53:51
【问题描述】:

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

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 返回码是成功的。如果无法注册新帐户,我希望将资源标记为失败。

我尝试只返回 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
  }

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

【问题讨论】:

    标签: terraform


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      这个问题已经被浏览了超过 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"]
      }
      

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

      【讨论】:

        猜你喜欢
        • 2023-02-21
        • 2012-12-14
        • 1970-01-01
        • 1970-01-01
        • 2020-04-12
        • 1970-01-01
        • 2015-06-01
        • 1970-01-01
        • 2013-06-12
        相关资源
        最近更新 更多