Creating a function to assume an AWS STS role in PowerShell $PROFILE - amazon-web-services

I have AWS credentials defined in my .aws/credentials like follows:
[profile source]
aws_access_key_id=...
aws_secret_access_key=...
[profile target]
role_arn = arn:aws:iam::123412341234:role/rolename
mfa_serial = arn:aws:iam::123412341234:mfa/mylogin
source_profile = source
...
and I would like to define functions in my $PROFILE to assume roles using AWS Tools for PowerShell in the said accounts because of MFA and credential lifetime of 1 hours.
The function looks like
function Use-SomeAWS {
Clear-AWSCredential
$Response=(Use-STSRole arn:aws:iam::123412341234:role/rolename -ProfileName target -RoleSessionName "my email").Credentials
$Creds=(New-AWSCredentials -AccessKey $Response.AccessKeyId -SecretKey $Response.SecretAccessKey -SessionToken $Response.SessionToken)
Set-AWSCredential -Credential $Creds
}
Copying & pasting the lines within the function work just fine, but sourcing the profile (. $PROFILE) and running the function (Use-SomeAWS) asks for the MFA code and seems to do its job, however, the credentials do not get correctly set for the session.
What am I doing wrong?
EDIT: With some further testing, this does work if I add -StoreAs someprofilename to the Set-AWSCredential and after that do Set-AWSCredential -ProfileName someprofilename but that kind of defeats the purpose.

Did you try the -Scope for Set-AWSCredential ? like this :
Set-AWSCredential -Credential $Creds -Scope global
https://docs.aws.amazon.com/powershell/latest/reference/items/Set-AWSCredential.html

Related

How do I obtain temporary AWS credentials for an unauthenticated role in PowerShell using a Cognito IdentityPool?

I was writing a PowerShell script that needed to access an AWS S3 bucket using an unauthenticated role via Cognito and had trouble finding much documentation. All of the documentation I was able to find for the AWS PowerShell SDK discussed storing your AccessKey and SecretKey but never how to get those credentials using Cognito when you aren't using a user pool.
There may be other ways to do this with PowerShell (I haven't been able to find them yet.) but you can obtain temporary credentials through Cognito using AWS's REST API.
The following PowerShell example shows how to:
Set your REST URL
Get an id from the Cognito Identity provider
Use the received id to request temporary credentials (AccessKey will begin with AS instead of AK)
Set the temporary credentials
For more information see:
AWS API Getting Credentials
AWS API GetCredentialsForIdentity
AWS API GetId
function Get-CognitoRestURL {
param(
[parameter(Mandatory)]$Region
)
return "https://cognito-identity.{0}.amazonaws.com/" -f $Region
}
function Get-AWSTempCredentials {
param(
[parameter(Mandatory)]$IdentityPoolId,
[parameter(Mandatory)]$Region
)
try {
$cognitoRestURL = Get-CognitoRestURL -Region $Region
$requestTempId = Invoke-RestMethod -Uri $cognitoRestURL -Method "POST" `
-Headers #{
"authority"=$cognitoRestURL
"x-amz-target"="AWSCognitoIdentityService.GetId"
"x-amz-user-agent"="aws-powershell callback"
} -ContentType "application/x-amz-json-1.1" -Body "{`"IdentityPoolId`":`"$($IdentityPoolId)`"}"
} catch {
Write-Error $_
#Request failed, we don't have the data we need to continue
break
}
try {
$tempCredentials = Invoke-RestMethod -Uri $cognitoRestURL -Method "POST" `
-Headers #{
"x-amz-target"="AWSCognitoIdentityService.GetCredentialsForIdentity"
"x-amz-user-agent"="aws-powershell callback"
} -ContentType "application/x-amz-json-1.1" -Body "{`"IdentityId`":`"$($requestTempId.IdentityId)`"}"
} catch {
Write-Error $_
#Request failed, we don't have the data we need to continue
break
}
return $tempCredentials
}
function Set-AWSTempCredentials {
param(
[parameter(Mandatory)]$AccessKeyId,
[parameter(Mandatory)]$SecretKey,
[parameter(Mandatory)]$SessionToken,
[parameter(Mandatory)]$ProfileName,
[parameter(Mandatory)]$Region
)
Set-AWSCredential -AccessKey $AccessKeyId -SecretKey $SecretKey -SessionToken $SessionToken -StoreAs $ProfileName
return Get-AWSCredential -ProfileName $ProfileName
}
$region = "us-west-1"
$IdentityPoolId = "us-west-1:12a01023-4567-123a-bcd1-12345a0b1abc"
$response = Get-AWSTempCredentials -IdentityPoolId $IdentityPoolId -Region $region
Set-AWSTempCredentials -AccessKeyId $response.Credentials.AccessKeyId `
-SecretKey $response.Credentials.SecretKey `
-SessionToken $response.Credentials.SessionToken `
-ProfileName MyTempCredentials `
-Region $region

aws-runas- 3.3.1 validation issue

I am trying to run the aws-runas to use AWS STS to do some development work using a specific user role. I already have access the required userrole access to the AWS account.
the command executed to run the aws sts
aws-runas.exe <profile_name>
[default]
output = json
region = <example1>
saml_auth_url = <url>
saml_username = <email>
saml_provider = <provider>
federated_username = <username>
credentials_duration = 8h
[profile <name>]
role_arn = arn:aws:iam::<account_id>:role/<role_name>
source_profile = <profile_name>
This is how I formed the config file which is located at C:\Users<NAME>.aws
Debug output is as the follows.
Does anyone have a clue of what's wrong in here ?

AWS SAM Incorrect region

I am using AWS SAM to test my Lambda functions in the AWS cloud.
This is my code for testing Lambda:
# Set "running_locally" flag if you are running the integration test locally
running_locally = True
def test_data_extraction_validate():
if running_locally:
lambda_client = boto3.client(
"lambda",
region_name="eu-west-1",
endpoint_url="http://127.0.0.1:3001",
use_ssl=False,
verify=False,
config=botocore.client.Config(
signature_version=botocore.UNSIGNED,
read_timeout=10,
retries={'max_attempts': 1}
)
)
else:
lambda_client = boto3.client('lambda',region_name="eu-west-1")
####################################################
# Test 1. Correct payload
####################################################
with open("payloads/myfunction/ok.json","r") as f:
payload = f.read()
# Correct payload
response = lambda_client.invoke(
FunctionName="myfunction",
Payload=payload
)
result = json.loads(response['Payload'].read())
assert result['status'] == True
assert result['error'] == ""
This is the command I am using to start AWS SAM locally:
sam local start-lambda -t template.yaml --debug --region eu-west-1
Whenever I run the code, I get the following error:
botocore.exceptions.ClientError: An error occurred (ResourceNotFound) when calling the Invoke operation: Function not found: arn:aws:lambda:us-west-2:012345678901:function:myfunction
I don't understand why it's trying to invoke function located in us-west-2 when I explicitly told the code to use eu-west-1 region. I also tried to use AWS Profile with hardcoded region - the same error.
When I switch the running_flag to False and run the code without AWS SAM everything works fine.
===== Updated =====
The list of env variables:
# env | grep 'AWS'
AWS_PROFILE=production
My AWS configuration file:
# cat /Users/alexey/.aws/config
[profile production]
region = eu-west-1
My AWS Credentials file
# cat /Users/alexey/.aws/credentials
[production]
aws_access_key_id = <my_access_key>
aws_secret_access_key = <my_secret_key>
region=eu-west-1
Make sure you are actually running the correct local endpoint! In my case the problem was that I had started the lambda client with an incorrect configuration previously, and so my invocation was not invoking what I thought it was. Try killing the process on the port you have specified: kill $(lsof -ti:3001), run again and see if that helps!
This also assumes that you have built the function FunctionName="myfunction" correctly (make sure your function is spelt correctly in the template file you use during sam build)

create a Powershell code that works with AWS: to list EC2 Key Pairs that are not in use by instances

I am looking to create a Powershell code that works with AWS: to list EC2 Key Pairs that are not in use by instances.
aws ec2 --profile default describe-key-pairs --query
KeyPairs[].[KeyName] --output text |xargs -I {} aws ec2 --profile
default describe-instances --filters Name=key-name,Values={} --query
Reservations[].Instances[].[KeyName,InstanceId] --output text| uniq
this code dosent work for powershell
You need to work with AWS Powershell Module.
The trick here is work with 2 cmdlet function - Get-EC2instance and Get-EC2KeyPair. First of all, you need to get all the keys that in use right now.
Later, you need to get all key pairs and filter them by basic for each and if statement.
Take a look at the following code snippet :
Import-Module AWSPowerShell
$keysInUse = #()
$keysNotInUse = #()
#Set AWS Credential
Set-AWSCredential -AccessKey "AccessKey" -SecretKey "SecretKey"
#Get ec2 key name from each instance
$allInstancesKeys = (Get-EC2instance -Region "YourRegion").Instances.KeyName
#Get all key based on region and check if there's an instance who use this key
Get-EC2KeyPair -Region "YourRegion" | % {
if($_.KeyName -notin $allInstancesKeys)
{
$keysNotInUse += $_.KeyName
}
else
{
$keysInUse += $_.KeyName
}
}
Write-Output "Keys not in use: $($keysNotInUse -join ',')\n
Keys in use: $($keysInUse -join ',')"
The instances i own and key name :
Output :
How to create new AccessKey and SecretKey - Managing Access Keys for Your AWS Account.
AWSPowerShell Module installation.
More about Get-EC2KeyPair Cmdlet.
From the docs :
Describes the specified key pairs or all of your key pairs.
More about Get-EC2instance
Returns information about instances that you own.

Powershell writing to AWS S3

I'm trying to get powershell to write results to AWS S3 and I can't figure out the syntax. Below is the line that is giving me trouble. If I run this without everything after the ">>" the results print on the screen.
Write-host "Thumbprint=" $i.Thumbprint " Expiration Date="$i.NotAfter " InstanceID ="$instanceID.Content" Subject="$i.Subject >> Write-S3Object -BucketName arn:aws:s3:::eotss-ssl-certificatemanagement
Looks like you have an issue with >> be aware that you can't pass the write-host function result into another command.
In order to do that, you need to assign the string you want into a variable and then pass it into the -Content.
Take a look at the following code snippet:
Install-Module AWSPowerShell
Import-Module AWSPowerShell
#Set AWS Credential
Set-AWSCredential -AccessKey "AccessKey" -SecretKey "SecretKey"
#File upload
Write-S3Object -BucketName "BucketName" -Key "File upload test" -File "FilePath"
#Content upload
$content = "Thumbprint= $($i.Thumbprint) Expiration Date=$($i.NotAfter) InstanceID = $($instanceID.Content) Subject=$($i.Subject)"
Write-S3Object -BucketName "BucketName" -Key "Content upload test" -Content $content
How to create new AccessKey and SecretKey - Managing Access Keys for Your AWS Account.
AWSPowerShell Module installation.
AWS Tools for PowerShell - S3 Documentation.