Skip to content

Instantly share code, notes, and snippets.

@petervandivier
Last active September 16, 2021 09:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petervandivier/2c126f650cf04f157dea7992125bcebf to your computer and use it in GitHub Desktop.
Save petervandivier/2c126f650cf04f157dea7992125bcebf to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
#
# must be dot-sourced to properly export, see https://stackoverflow.com/a/16619261/4709762
# https://aws.amazon.com/premiumsupport/knowledge-center/authenticate-mfa-cli/
#
profile=${1:-default}
if [ "${profile}" != default ]; then
grep "^\[profile ${profile}\]$" ~/.aws/config > /dev/null || echo "Profile [${profile}] not configured in ~/.aws/config"
grep "^\[profile ${profile}\]$" ~/.aws/credentials > /dev/null || echo "Profile [${profile}] credentials not found at ~/.aws/credentials"
fi
caller_identity=$(aws sts get-caller-identity --profile "$profile" | jq --compact-output)
echo "Supply the following for aws org $(echo "$caller_identity" | jq --raw-output .Account)"
read -sp "AWS_MFA_Code: " AWS_MFA_Code
echo
my_arn=$(echo "${caller_identity}" | jq --raw-output .Arn)
mfa_query_filter=".VirtualMFADevices[] | select (.User.Arn == \"${my_arn}\")"
# only for virtual device e.g. google authenticator
# use list-mfa-devices for hardware MFA
device_arn=$(
aws iam list-virtual-mfa-devices \
--profile "${profile}" \
| jq --compact-output "${mfa_query_filter}" \
| jq --raw-output .SerialNumber
)
credential=$(
aws sts get-session-token \
--profile "${profile}" \
--serial-number "${device_arn}" \
--token-code "${AWS_MFA_Code}" \
| jq --compact-output .Credentials
)
# echo "$credential" | jq
AWS_ACCESS_KEY_ID=$(echo "$credential" | jq --raw-output .AccessKeyId)
AWS_SECRET_ACCESS_KEY=$(echo "$credential" | jq --raw-output .SecretAccessKey)
AWS_SESSION_TOKEN=$(echo "$credential" | jq --raw-output .SessionToken)
export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
export AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}
#!/usr/bin/env pwsh
#Requires -Modules AWSPowerShell
# TODO: dispose of vars properly...
# not sure atm why they persist in caller scope when dot-sourced :\
[cmdletbinding()]param(
[Parameter(Mandatory=$true)]$AwsMfaCode
,$ProfileName = "default"
)
$serial_number = (aws sts get-caller-identity --profile $ProfileName --output text --query 'Arn').Replace('user','mfa')
$json = aws sts get-session-token --profile $ProfileName --serial-number $serial_number --token-code $AwsMfaCode
$obj = $json | ConvertFrom-Json
if($null -ne $obj.Credentials){
Set-item -path env:AWS_ACCESS_KEY_ID -value $obj.Credentials.AccessKeyId
Set-item -path env:AWS_SESSION_TOKEN -value $obj.Credentials.SessionToken
Set-item -path env:AWS_SECRET_ACCESS_KEY -value $obj.Credentials.SecretAccessKey
Write-Host "Session credential set for profile [$ProfileName]" -ForegroundColor Yellow
if($null -eq (Get-DefaultAWSRegion)){
$ProfileKey = $ProfileName
if($ProfileKey -eq 'default'){$ProfileKey = "profile $ProfileKey"}
$DefaultRegion = (ConvertFrom-IniFile ~/.aws/config)[$ProfileKey].region
if((Get-AWSRegion).Region -contains $DefaultRegion){
$DefaultRegion | Set-DefaultAWSRegion
Write-Host "Default AWS Region set to [$DefaultRegion]" -ForegroundColor Yellow
}
else {
Write-Host "No default AWS Region set. Browse valid options with Get-AWSRegion" -ForegroundColor Red
Write-Host "Default AWS region not set or [$DefaultRegion] is not a valid AWS Region" -ForegroundColor Red
Write-Host "Use the -Region parameter or set manually as needed. Examine valid regions with Get-AWSRegion" -ForegroundColor Yellow
}
}
}
Function ConvertFrom-IniFile ($file) {
<#
.LINK
https://stackoverflow.com/a/422529/4709762
#>
$ini = @{}
# Create a default section if none exist in the file. Like a java prop file.
$section = "NO_SECTION"
$ini[$section] = @{}
switch -regex -file $file {
"^\[(.+)\]$" {
$section = $matches[1].Trim()
$ini[$section] = @{}
}
"^\s*([^#].+?)\s*=\s*(.*)" {
$name,$value = $matches[1..2]
# skip comments that start with semicolon:
if (!($name.StartsWith(";"))) {
$ini[$section][$name] = $value.Trim()
}
}
}
$ini
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment