我有一个Shell脚本,该脚本从AWS SSM参数存储中提取参数,并在某些cURL命令中将其使用到第三方API。如果我通过终端手动执行每个命令,它们都可以正常运行而不会出现问题。但是,一旦将它们放在下面的脚本中,用于创建AWS账户连接器的cURL命令就会不断抛出500 Internal service错误。
下面是一个代码段:
#!/bin/bash
# Creating random guid to use for ExternalId
UUID=$(uuidgen)
echo "UUID: $UUID"
# Replacing ExternalId in assumepolicy doc with created guid
$SED_COMMAND -i "s/\"sts:ExternalId\": \".*\"/\"sts:ExternalId\": \"${UUID}\"/g" ./trust-policy.json
# Create new cross-account role with assume role policy
echo "Creating new cross-account role."
aws iam create-role --role-name ${ROLENAME} --assume-role-policy-document file://trust-policy.json
# Attach role policy to newly created role
aws iam put-role-policy --role-name ${ROLENAME} --policy-name ${POLICYNAME} --policy-document file://inline-policy.json
# Grabbing role arn
ARN=$(aws iam get-role --role-name ${ROLENAME} | jq -r '.Role.Arn')
# Logging into SaaS instance; retrieving SID for subsequent API calls
SID=`curl -ks -H "Content-Type: application/json" "Accept: application/json" -X POST "${URL}/rest/authentication/login" -d '{"dsCredentials":{"userName":"'${USER_ID}'","password":"'${PASSWORD}'"}}'`
# Create AWS account connector
echo "Creating AWS account connector."
curl -ks --cookie "sID=${SID}" -H "Content-Type: application/json" "Accept: application/json" -X POST "${URL}/rest/cloudaccounts/aws" -d '{"AddAwsAccountRequest": {"useInstanceRole": false,"crossAccountRole": {"roleArn": "'${ARN}'","externalId": "'${UUID}'"},"workspacesEnabled": false}}'
# Log out of SaaS instance
echo "Logging out."
curl -k -X DELETE ${URL}/rest/authentication/logout?sID=${SID}
第一个cURL语句在脚本中可以正常工作,该脚本可以获取用于身份验证的SID。
SID=`curl -ks -H "Content-Type: application/json" "Accept: application/json" -X POST "${URL}/rest/authentication/login" -d '{"dsCredentials":{"userName":"'${USER_ID}'","password":"'${PASSWORD}'"}}'`
但是,通过外壳程序脚本{"error":{"message":"Internal server error"}}
curl -ks --cookie "sID=${SID}" -H "Content-Type: application/json" "Accept: application/json" -X POST "${URL}/rest/cloudaccounts/aws" -d '{"AddAwsAccountRequest": {"useInstanceRole": false,"crossAccountRole": {"roleArn": "'${ARN}'","externalId": "'${UUID}'"},"workspacesEnabled": false}}'
如果我使用 exact 相同的cURL命令并在终端中手动执行,则可以正常运行。我也可以在Postman中进行这项工作。
在Postman中,我发现如果请求中的一部分数据格式错误或为空,则会返回相同的“内部服务器错误”,因此我的直觉是请求正文有问题;但是,我可以在终端上通过bash -x运行确切的curl命令输出,并且可以正常工作。
例如,这是使用以下命令运行上述脚本的输出:bash -x ./cloudConnectorAutomation.sh
+ echo 'Creating AWS account connector.'
Creating AWS account connector.
+ curl -ks --cookie sID=XXXX -H 'Content-Type: application/json' 'Accept: application/json' -X POST https://XXXX/rest/cloudaccounts/aws -d '{"AddAwsAccountRequest": {"useInstanceRole": false,"crossAccountRole": {"roleArn": "arn:aws:iam::XXXXXXXXXXXX:role/XXXX","externalId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"},"workspacesEnabled": false}}'
{"error":{"message":"Internal server error"}}
如果我直接从终端的输出中复制并粘贴 exact 相同的curl命令并执行该命令,它将完美执行。
我记下了脚本和终端中运行的命令的curl -v输出,除了不同的SID(由于不同的身份验证会话)外,它们是相同的。在脚本中运行的一个显示为状态代码:< HTTP/1.1 500
,而我手动运行的一个显示为状态代码:< HTTP/1.1 200
。
在最后的努力中,我什至测试了调用python脚本而不是使用cURL。下面的Python脚本。在本文开头的初始脚本中,它是在有问题的cURL请求的地方调用的:
import requests
import sys
import json
SID = sys.argv[1]
URL = sys.argv[2]
ARN = sys.argv[3]
UUID = sys.argv[4]
# Do not proceed if required parameters are empty
if not SID or not URL or not ARN or not UUID:
print ("\nERROR: Required parameters are empty.")
print ("SID: " + SID)
print ("URL: " + URL)
print ("ARN: " + ARN)
print ("UUID: " + UUID)
exit()
endpoint = URL + '/rest/cloudaccounts/aws'
cookies = {
'sID': SID
}
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
payload = {'AddAwsAccountRequest': {'useInstanceRole': False,'crossAccountRole': {'roleArn': ARN,'externalId': UUID},'workspacesEnabled': False}}
response = requests.post(endpoint, headers=headers, cookies=cookies, data=json.dumps(payload), verify=False)
它返回相同的内部服务器错误:
Creating AWS account connector.
+ python3 ./account_connector.py XXXX https://XXXX.com arn:aws:iam::XXXXXXXXX:role/XXXX XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
{"error":{"message":"Internal server error"}}
但是,如果我在ipython中逐行执行,它会完美地工作。
我在这里不知所措,并且花了整整一天的时间试图弄清楚这一点。
再次,我真正地相信问题是我的数据块以某种方式变形,但是我看不到它在哪里。对于为什么我可以使用完全相同的cURL命令并且它可以在终端中运行,我也感到困惑。我正在研究通过终端与Shell脚本运行cURL命令时是否存在细微差别或细微差别,但我没有发现存在。
在此方面的任何帮助将不胜感激。
答案 0 :(得分:1)
您能尝试逃脱吗:
"{\"AddAwsAccountRequest\": {\"useInstanceRole\": false,\"crossAccountRole\": {\"roleArn\": \"${ARN}\",\"externalId\": \"${UUID}\"},\"workspacesEnabled\": false}}"
从终端运行与运行脚本相比,在某些逃避方面有一些微妙之处,如此处所述:curl works, but won't execute in BASH script
让我知道是否有帮助!