I have an AWS Batch Job which is a .NET CORE app running as a container which downloads from an SFTP server a CSV parses it and inserts data into AWS RDS.
When the CSV is corrupt the job is failing and is supposed to send a SNS notification, instead I see the following error in CloudWatch logs.
"Message": "User: arn:aws:sts::654001826221:assumed-role/fileimportworker-batch/5f77c736e4e64c2d82df278800ec4f25 is not authorized to perform: SNS:Publish on resource: arn:aws:sns:eu-west-1:accountIdHere:Test-SNS-Batch",
My IAM role attached to the batch Job role has SNS:Published allowed, S3 allowed, also provides read access to 2 secrets in Secret Manager. S3 and SecretManager access work, the task is able to download the file from SFTP and put it to S3 and also to read the RDS password from secret manager.
AWS Batch Job may use credentials from a container instead of your environment variables. You have to look at credential precedence.
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-precedence
The AWS CLI uses credentials and configuration settings located in
multiple places, such as the system or user environment variables,
local AWS configuration files, or explicitly declared on the command
line as a parameter. Certain locations take precedence over others.
The AWS CLI credentials and configuration settings take precedence in
the following order:
Command line options – Overrides settings in any other location. You
can specify --region, --output, and --profile as parameters on the
command line.
Environment variables – You can store values in your system's
environment variables.
CLI credentials file – The credentials and config file are updated
when you run the command aws configure. The credentials file is
located at ~/.aws/credentials on Linux or macOS, or at
C:\Users\USERNAME.aws\credentials on Windows. This file can contain
the credential details for the default profile and any named profiles.
CLI configuration file – The credentials and config file are updated
when you run the command aws configure. The config file is located at
~/.aws/config on Linux or macOS, or at C:\Users\USERNAME.aws\config
on Windows. This file contains the configuration settings for the
default profile and any named profiles.
Container credentials – You can associate an IAM role with each of
your Amazon Elastic Container Service (Amazon ECS) task definitions.
Temporary credentials for that role are then available to that task's
containers. For more information, see IAM Roles for Tasks in the
Amazon Elastic Container Service Developer Guide.
Instance profile credentials – You can associate an IAM role with each
of your Amazon Elastic Compute Cloud (Amazon EC2) instances. Temporary
credentials for that role are then available to code running in the
instance. The credentials are delivered through the Amazon EC2
metadata service. For more information, see IAM Roles for Amazon EC2
in the Amazon EC2 User Guide for Linux Instances and Using Instance
Profiles in the IAM User Guide.
P.S. To intergate AWS Batch with SNS without coding, you can use the Eventbridge rule to listen to event patterns from AWS Batch. You just select the target of the rule to publish the message on the SNS topic you want.
https://docs.aws.amazon.com/batch/latest/userguide/batch_sns_tutorial.html
Related
I'm trying to create a botocore session (that does not use my local AWS credentials on ~/.aws/credentials). In other words, I want to create a "burner AWS account". With that burner credentials/session, I want to setup an STS client and with that client, assume a role in order to access a DynamoDB database. Can someone provide some example code which accomplishes exactly this?
Because if I want my system to go into production environment, I CANNOT store the AWS credentials on Github because AWS will scan for it. I'm trying to implement a workaround such that we don't have to store ~/.aws/credentials file on Github.
The running a task in Amazon ECS, simply assign an IAM Role to the task.
Amazon ECS will then generate temporary credentials for that IAM Role. Any code that uses an AWS SDK (such as boto3 for Python) knows how to access those credentials via the metadata service.
The result is that your code using boto3 will automatically receive credentials that have the permissions associated with the IAM Role assigned to the task.
See: IAM roles for tasks - Amazon Elastic Container Service
I'm learning AWS using the AWS CLI and LocalStack.
I'm working with tutorials such as this, which describe how to create a S3 bucket and upload a file to it.
What I'd like to understand is the role of users in relation to AWS commands, and whether or not there is a relationship between a user and a profile (the latter is created when you run the aws configure CLI command).
When I run a AWS CLI command such as aws --endpoint-url=http://localhost:4572 s3 cp ./foo.json s3://my-bucket/path/to/foo.json what user am I running that command as? I have not explicitly created any users using the AWS IAM CLI or by other means. Is a profile implicitly a user? I.e. when I run aws configure, does the default profile created mean a user named default is created in AWS IAM?
Well, it's easy to check actually.
https://docs.aws.amazon.com/cli/latest/reference/sts/get-caller-identity.html
Is a profile implicitly a user?
No, profile is just that - credentials profile. Whether it's a user or a role, AWS CLI doesn't care as long as those credentials are valid.
when I run aws configure, does the default profile created mean a user named default is created in AWS IAM
Going from previous point, no. Nothing is done implicitly in IAM. When you run aws configure you supply credentials that already exist, not the other way around.
On my client's AWS account, security credentials are generated everytime we login to their AWS sandbox account. This credentials file is automatically generated and downloaded via a Chrome plugin(SAML to AWS STS Key Conversion).
We then have to place the generated content to the ./aws/credentials file inside an EC2 instance in the same AWS account. This is little inconvenient as we have to update the generated credentials and session_token into the credentials file inside the EC2 instance every time we launch a Terraform script.
Is there any way we can attach any role so that we can just use the EC2 instance without entering the credentials into the credentials file.
Please suggest.
Work out what a reasonable, minimal set of permissions the Terraform script needs to create its AWS resources, then create an IAM role with those permissions, then add that IAM role to the instance (or launch a new instance with the role). Don't have a ~/.aws/credentials file on the instance or it will take precedence over the IAM role-based credentials.
I have EC2 instance.
I'm trying to call aws s3 from it but getting an error
Unable to locate credentials
I tried aws configure which does show everything as empty.
I see IAM role for S3 full permissions assigned to this instance.
Do I need any additional configuration?
If you run aws on an Amazon EC2 instance that has an assigned role, then it should find the credentials automatically.
You can also use this to view the credentials from the instance:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
The role name should be listed. Then append it to the command:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE-NAME/
You should then be presented with AccessKeyId, SecretAccessKey, etc.
If that information does not appear, it suggests that your role is not correctly attached to the instance. Try unassigning the role and then assign it to the instance again.
First read and follow John Rotenstein's advice.
The SDK (from which the CLI is built from) searches for credentials in the following order:
Environment variables (AWS_ACCESS_KEY_ID ....)
Default Profile (credentials file)
ECS Container Credentials (if running on ECS)
Instance Profile
After verifying that your EC2 instance has credentials in the metadata, double check 1 & 2 to make sure that there are no other credentials present even if empty.
Note: This link argues with my last point (empty credentials file). I never create (store) credentials on an EC2 instance and I only use IAM Roles.
Instance Metadata
For different AWS services, I need different IAM users to secure the access control. Sometimes, I even need to use different IAM user credentials within a single project in a EC2 instance. What's the proper way to manage this and how I can deploy/attach these IAM user credentials to a single EC2 instance?
While I fully agree with accepted answer that using static credentials is one way of solving this problem, I would like to suggest some improvements over it (and proposed Secrets Manager).
What I would advise as architectural step forward to achieve full isolation of credentials, having them dynamic, and not stored in central place (Secrets Manager proposed above) is dockerizing application and running on AWS Elastic Container Service (ECS). This way you can assign different IAM role to different ECS Tasks.
Benefits over Secrets Manager solution
- use case of someone tampering with credentials in Secrets Manager is fully avoided, as credentials are of dynamic nature (temporary, and automatically assumed through SDKs)
Credentials are managed on AWS side for you
Only ECS Service can assume this IAM role, meaning you can't have actual person stealing the credentials, or developer connecting to production environment from his local machine with this credentials.
AWS Official Documentation for Task Roles
The normal way to provide credentials to applications running on an Amazon EC2 instance is to assign an IAM Role to the instance. Temporary credentials associated with the role when then be provided via Instance Metadata. The AWS SDKs will automatically use these credentials.
However, this only works for one set of credentials. If you wish to use more than one credential, you will need to provide the credentials in a credentials file.
The AWS credentials file can contain multiple profiles, eg:
[default]
aws_access_key_id = AKIAaaaaa
aws_secret_access_key = abcdefg
[user2]
aws_access_key_id = AKIAbbbb
aws_secret_access_key = xyzzzy
As a convenience, this can also be configured via the AWS CLI:
$ aws configure --profile user2
AWS Access Key ID [None]: AKIAbbbb
AWS Secret Access Key [None]: xyzzy
Default region name [None]: us-east-1
Default output format [None]: text
The profile to use can be set via an Environment Variable:
Linux: export AWS_PROFILE="user2"
Windows: set AWS_PROFILE="user2"
Alternatively, when calling AWS services via an SDK, simply specify the Profile to use. Here is an example with Python from Credentials — Boto 3 documentation:
session = boto3.Session(profile_name='user2')
# Any clients created from this session will use credentials
# from the [user2] section of ~/.aws/credentials.
dev_s3_client = session.client('s3')
There is an equivalent capability in the SDKs for other languages, too.