bashshellcurl

Sending variable inside curl with '' shielding


I can execute api-call using terraform, but not bash.

This terraform code works:

curl -X POST https://circleci.com/api/v2/project/gh/some-organization/${var.repository_name}/envvar \
 -H 'Content-Type: application/json' \
 -H 'Circle-Token: ${data.aws_ssm_parameter.ct[0].value}' \
 -d '{"name":"AWS_ACCOUNT_ID_${upper(var.environment)}","value":"${data.aws_caller_identity.current.account_id}"}'

This is my bash code that doesn't work:

#!/bin/bash
user=$1
repo=$2
lower_env=$3
env=$(echo "$lower_env" | tr '[:lower:]' '[:upper:]')
token="1234567890"

......
NEW_ACCESS_KEY_ID="$(aws iam list-access-keys --user-name $user | jq -r '.AccessKeyMetadata[].AccessKeyId')"
......

  curl -X POST https://circleci.com/api/v2/project/gh/some-organization/$repo/envvar \
      -H 'Content-Type: application/json' \
      -H 'Circle-Token:${token}' \
      -d '{"name":"AWS_ACCESS_KEY_ID_${env}","value":"\'$NEW_ACCESS_KEY_ID'\"}'

As I understand, main problem happens with passing variable token inside curl, I tried shielding - ' '\ - but no luck.

      -H 'Content-Type: application/json' \
      -H 'Circle-Token: \'$token'\' \
      -d '{"name":"AWS_SECRET_ACCESS_KEY_${upper(\'$env'\}","value":"\'$NEW_SECRET_ACCESS_KEY'\"}'

I tried to echo curl itself from bash, it looks correct:

curl -X POST https://circleci.com/api/v2/project/gh/some-ogranization/repo-from-token/envvar -H 'Circle-Token: 1234567890'

The working code, the solution:

  curl -X POST "https://circleci.com/api/v2/project/gh/some-organization/$repo/envvar" \
      -H "Content-Type: application/json" \
      -H "Circle-Token: $token" \
      -d "{\"name\":\"AWS_ACCESS_KEY_ID_${env}\",\"value\":\"$NEW_ACCESS_KEY_ID\"}"

Solution

  • I think the problem is with the syntax for passing the Circle-Token header,you used ${data.aws_ssm_parameter.ct[0].value} to interpolate the value of the Circle-Token header, and you used single quotes (') around the Circle-Token header value, which prevents variable interpolation,so just use double quotes (") !

    #!/bin/bash
    user=$1
    repo=$2
    lower_env=$3
    env=${lower_env^^}
    token="1234567890"
    
    ......
    
    NEW_ACCESS_KEY_ID="$(aws iam list-access-keys --user-name $user | jq -r '.AccessKeyMetadata[].AccessKeyId')"
    
    ......
    
    curl -X POST "https://circleci.com/api/v2/project/gh/some-organization/$repo/envvar" \
        -H "Content-Type: application/json" \
        -H "Circle-Token: $token" \
        -d "{\"name\":\"AWS_ACCESS_KEY_ID_${env}\",\"value\":\"$NEW_ACCESS_KEY_ID\"}"
    

    If you like, you could reduce the escaping in the -d argument by only exposing the variables to the shell for interpretation rather than the whole argument string either by concatenation:

    curl ...
        -d '{"name":"AWS_ACCESS_KEY_ID_'"${env}"'","value":"'"$NEW_ACCESS_KEY_ID"'"}'
    

    or calling printf:

    curl ...
        -d "$(printf '{"name":"AWS_ACCESS_KEY_ID_%s","value":"%s"}' "$PWD" "$HOME")"
    

    or by populating a variable to be used as that argument:

    data='{"name":"AWS_ACCESS_KEY_ID_'"${env}"'","value":"'"$NEW_ACCESS_KEY_ID"'"}'
    

    or:

    printf -v data '{"name":"AWS_ACCESS_KEY_ID_%s","value":"%s"}' "$env" "$NEW_ACCESS_KEY_ID"
    

    followed by:

    curl ...
        -d "$data"