Better Living Through Narratology

Using AWS STS on Windows to populate Terraform credentials

When using the AWS provider in Terraform, one of the methods of authentication is the shared credentials file.  The notion of keeping a long-term AWS Access key and Secret key in here is unsettling, but it’s a great place to keep a short-term token issued by the AWS Security Token Service (STS).  There are posts about automating the population of tokens with Linux commands and some with JQ but when supporting clients in a Windows environment who don’t operate Linux subsystems and aren’t comfortable parsing JSON, a little old-fashioned Windows scripting comes to the rescue.

The following bat file uses AWS CLI to issue an assume-role command to obtain a short-term token for authentication and parses the JSON response for the elements we need.  It uses those elements to populate a shared credential file that we specify in our provider.tf file.

The following assumptions are made:

  1. Your AWS CLI installation is in the default location and your default credentials have authority to (hopefully, ONLY) run sts assume-role.
  2. This script is run from the same directory that contains your terraform.tfvars file.
  3. Your terraform.tfvars file contains variables with values for the profile name you’d like to use, the target AWS account ID and (in this case) the AWS partition (aws for commercial and aws-us-gov for GovCloud).
  4. Your target AWS account has an IAM role named TerraformAdmin that has all the permissions you need to provision infrastructure and a trust policy that allows you to assume it.

 

set AWS_DEFAULT_PROFILE=default
set AWS_CONFIG_FILE=%USERPROFILE%\.aws\config
set AWS_CREDENTIAL_FILE=%USERPROFILE%\.aws\credentials
REM echo %AWS_CONFIG_FILE%
echo Checking for terraform.tfvars in the current directory.
IF NOT EXIST terraform.tfvars (
echo No terraform.tfvars file present. Make sure you are in the right directory.
pause
exit
)


for /f "tokens=1,3" %%a in ('type terraform.tfvars ^| find "aws_profile"') do (
IF /I "%%a" == "aws_profile" set AWS_PROFILE=%%b
)
for /f "tokens=1,3" %%a in ('type terraform.tfvars ^| find "aws_account_id"') do (
IF /I "%%a" == "aws_account_id" set AWS_ACCOUNT_ID=%%b
)
for /f "tokens=1,3" %%a in ('type terraform.tfvars ^| find "aws_partition"') do (
IF /I "%%a" == "aws_partition" set AWS_PARTITION=%%b
)


SET ADMIN_ROLE_ARN_ON_TARGET=arn:%AWS_PARTITION:"=%:iam::%AWS_ACCOUNT_ID%:role/TerraformAdmin
SET AWS_PROFILE=%AWS_PROFILE:"=%
REM Now assuming role and writing to file.


echo Now running: aws sts assume-role --role-arn %ADMIN_ROLE_ARN_ON_TARGET% --role-session-name %username% --output json
aws sts assume-role --role-arn %ADMIN_ROLE_ARN_ON_TARGET% --role-session-name %username% --output json > "%USERPROFILE%\.aws\tf-shared-creds.txt"

echo Setting shared credentials file...
SET AWS_SHARED_CREDENTIALS_FILE=%USERPROFILE%\.aws\tf-shared-creds.txt

for /f "tokens=1,2 delims={},: " %%a in ('type %USERPROFILE%\.aws\tf-shared-creds.txt ^| find "AccessKeyId"') do (
IF /I %%a=="AccessKeyId" set STS_AWS_ACCESS_KEY_ID=%%b
)
for /f "tokens=1,2 delims={},: " %%a in ('type %USERPROFILE%\.aws\tf-shared-creds.txt ^| find "SecretAccessKey"') do (
IF /I %%a=="SecretAccessKey" set STS_AWS_SECRET_ACCESS_KEY=%%b
)
for /f "tokens=1,2 delims={},: " %%a in ('type %USERPROFILE%\.aws\tf-shared-creds.txt ^| find "SessionToken"') do (
IF %%a=="SessionToken" set STS_AWS_SESSION_TOKEN=%%b
)
for /f "tokens=1,2,3,4 delims=T:Z " %%a in ('type %USERPROFILE%\.aws\tf-shared-creds.txt ^| find "Expiration"') do (
IF /I %%a=="Expiration" set STS_EXPIRATION="%%c:%%d% UTC"
)

echo [%AWS_PROFILE%] > %AWS_SHARED_CREDENTIALS_FILE%
echo aws_access_key_id = %STS_AWS_ACCESS_KEY_ID:"=% >> %AWS_SHARED_CREDENTIALS_FILE%
echo aws_secret_access_key = %STS_AWS_SECRET_ACCESS_KEY:"=% >> %AWS_SHARED_CREDENTIALS_FILE%
echo aws_session_token = %STS_AWS_SESSION_TOKEN:"=% >> %AWS_SHARED_CREDENTIALS_FILE%
echo last_updated = %date% >> %AWS_SHARED_CREDENTIALS_FILE%

echo Your STS Token for the %AWS_PROFILE% account expires at %STS_EXPIRATION:"=%
echo You may now run Terraform against the target account.

Posted in Uncategorized | No Comments