Attach AWS IAM Profile to Azure VM - amazon-web-services

Is there a way where to attach an AWS IAM profile to an Azure VM.
I'm trying to develop a common infrastructure for Azure and AWS and i want to use resources which are in AWS from an Azure VM.
I know this can do this by exporting AWS creds to Azure VM but is there a way where I can attach an already existing AWS IAM profile to the Azure VM (if not directly may be through an interface or a service?) and access the resources (which how is I'm doing from an ec2 instance currently) ?

Sadly you can't do this. IAM instance profiles are only valid and usable from ec2 instances. You can't use instance profiles from outside of aws.
As you mentioned, you have to explicitly provide aws credentials to your azure vm. For example by creating .aws/ folder with aws profile.

You should be able to achieve what you are looking for by using the same IAM role for both the EC2 instance profile and a managed identity assigned to your Azure VM.
From my limited understanding of AWS, the instance profile identifies your EC2 instance, so you cant use it directly.
To use the same role for both EC2 and Azure VM, here is how I would try this out:
First, familiarize yourself with how you can assign an Azure managed identity a role in AWS. I wrote this blog post recently to show how Managed identities can be granted access to AWS resources: https://blog.identitydigest.com/azuread-access-aws/
Now rather than create a new role as mentioned in the blog, you can reuse the role in your EC2 instance, by adding a trust relationship for the managed identity to AssumeRoleWithWebIdentity.
So the trust relationship for your existing role used in your EC2 profile will look something as follows: (please note, I have not tried multiple statements in a role but expect this to work based on the AWS documentation)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<your account>:oidc-provider/sts.windows.net/<your azure ad tenant>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"sts.windows.net/<your tenant>:aud": "app audience or managed identity client_id",
"sts.windows.net/<your tenant>:sub": "in case you want to also include sub"
}
}
}
]
}
Now if you assign the managed identity to the VM, it should be able to access the same resources as your EC2 instance.

Related

AWS Policies explained?

I am learning AWS and I have the following task in an online training course:
Configure the MongoDB VM as highly privileged – configure an instance
profile to the VM and add the permission “ec2:*” as a custom policy.
I am trying to work out what that means. Is the task asking for a role that enables the VM instance to have full control over all EC2 resources?
If I understand it correctly, then I think the following policy would implement it.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:*"
],
"Effect": "Allow",
"Resource": "arn:aws:ec2:*:*:instance"
}
]
}
My understanding is that this policy is saying any EC2 instance can perform any EC2 action. Is that right?
I would say you are almost correct. Roles are attached to individual services which means your particular VM can perform any Ec2 action on this resource arn:aws:ec2:*:*:instance.
There is a difference in saying any ec2 can perform ec2 action instead that ec2 instance can perform any ec2 action to which this role is attached.

Does anyone know where this goes in the instances?

{
"Sid": "ElasticBeanstalkHealthAccess",
"Action": [
"elasticbeanstalk:PutInstanceStatistics"
],
"Effect": "Allow",
"Resource": [
"arn:aws:elasticbeanstalk:*:*:application/*",
"arn:aws:elasticbeanstalk:*:*:environment/*"
]
}
That's a part of the IAM profile for the elastic beanstalk instance.
If you choose AWSElasticBeanstalkWebTier or AWSElasticBeanstalkWorkerTier as IAM Instance profile, the ElasticBeanstalkHealthAccess permissions will be added already.
See https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/iam-instanceprofile.html
There are two IAM roles associated with an Elastic Beanstalk Environment:
Service role: used to manage the environment
Instance role: role assumed by the running application. It is used to provide access to other AWS services.
You need to find your instance role in IAM console and attach the permission that you see in the documentation. This will allow your application to send statistics.

How to limit AWS autoscaling to not allow the use of a specific role?

I have a IAM role dedicated for EC2, but I would like to restrict use of this role to only certain services eg. Service Catalog. I can't do it on autoscaling level - it uses service linked role which is impossible to edit. I believe that I can somehow block that access on trusted relationship policy level on the target role. I have tried many things but nothing works for me. I think the main problem is that this role is not directly used by autoscaling, but this is a process chain which starts from autoscaling and ends on ec2. Role is no strictly used by the service but is passed through instance profile.
Any suggestions how to approach this topic ?
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123344566:root"
],
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": "????"
}
}
}
]
}
BG
Seba
It appears that your requirement is:
You have a privileged IAM Role (let's call it Admin Role)
You want to allow non-Admins to create Amazon EC2 Auto Scaling groups
You do not want them to be able to attach the Admin Role to the Auto Scaling group because they could login to the resulting instances and gain privileged access
I think that you will need to control the ability to create Launch Templates and Launch Configurations:
Creating a Launch Template requires the ec2:CreateLaunchTemplate permission
Creating a Launch Configuration requires the autoscaling:createLaunchConfiguration permission
If users are not allowed to create these templates, then they cannot select a role. They would need to use an existing template to launch the Auto Scaling group.

connecting to aws elastic search with nodejs aws sdk

what is the best approach in using aws elastic search with nodejs? I am using aws ecs ec2 instance for running my docker containers and is using the IAM role to accessing the other aws resource like S3 bucket and dynamodb from nodejs.
Can we use the same procedure for accessing the aws elastic search endpoint too?
I added an inline policy with the existing role and added the elastic search end point arn. but the nodejs sdk is not able to connect to the ES. when the aws key and id is added as environment variable in task definition it starts working. But I dont need to use that method as it will conflict with the other aws resource. (looks like the dev team is configured the program such that it looks for env)
It for sure is not the best method but you can also use a ip based restriction. We currently use this and it works fine. Just set an elastic ip on your ec2 instance (if you haven't already) and set the ip address in the access policy like this:
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"XXX.XXX.XXX.XXX",
]
}
}
For anybody else stumbling across this, here's a few things I learnt whilst I was stuck on something similar:
EC2's role ARN can be added in the access policy for your Elasticsearch domain along with the permissions you want the role to have. For eg. for an EC2 running with role "aws-ec2" needing permissions to make HTTP GET requests to ES, you could have the following in your ES domain access policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<ACCOUNT_ID>:role/aws-ec2",
]
},
"Action": "es:ESHttpGet",
"Resource": "arn:aws:es:<REGION>:<ACCOUNT_ID>:domain/<DOMAIN_NAME>/*"
}
]
}
Any requests made by an EC2 instance running with role "aws-ec2" in your account will have access to elasticsearch.
Note that if you have trouble getting credentials, try the following:
AWS.config.getCredentials(function(err) {
if (err) console.log(err.stack);
// credentials not loaded
else {
// credentials are loaded and can be accessed using
AWS.config.credentials.accessKeyId, AWS.config.credentials.secretAccessKeyId etc.
}
});
This will usually pull the credentials in like magic, I have a theory about how it works (tl:dr; I think it pulls them from the EC2 instance metadata by making a request to a fixed IP) but it's unproven so I won't embarrass myself until I know more. Note that this should work even if you don't have credentials stored in your environment or in the shared credentials file.

How to allow users to launch EC2 instances only from Service Catalog?

I've created a Service Catalog portfolio and product intending to allow users to launch their own quality assurance environments. I have given a selection of users the AWS Managed Policy "ServiceCatalogEndUserFullAccess" (below) so they can launch products, however they seem to also require individual permissions for the resources created by the template (in this case, just an EC2 and ELB).
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"catalog-user:*",
"cloudformation:CreateStack",
"cloudformation:DeleteStack",
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeStacks",
"cloudformation:GetTemplateSummary",
"cloudformation:SetStackPolicy",
"cloudformation:ValidateTemplate",
"cloudformation:UpdateStack",
"servicecatalog:DescribeProduct",
"servicecatalog:DescribeProductView",
"servicecatalog:DescribeProvisioningParameters",
"servicecatalog:ListLaunchPaths",
"servicecatalog:ProvisionProduct",
"servicecatalog:SearchProducts",
"s3:GetObject"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"servicecatalog:DescribeRecord",
"servicecatalog:ListRecordHistory",
"servicecatalog:ScanProvisionedProducts",
"servicecatalog:TerminateProvisionedProduct",
"servicecatalog:UpdateProvisionedProduct"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"servicecatalog:userLevel": "self"
}
}
}
]
}
As such, the template fails in CloudFormation and rolls back with an error like the following:
API:ec2:runInstances - You are not authorized to perform this operation.
Ideally I'd like to restrict the user's ability to launch an EC2 either from Service Catalog only, or perhaps more specifically our staging VPC, but neither seems possible from what I've read currently. Is there any way to grant this level of granular permission such that the user can only launch the resources in the particular Service Catalog product they've chosen?
Your policy has granted users permission to use Service Catalog, but that is not sufficient to permit them to launch the actual resources.
There are two ways to grant permission to launch resources (eg Amazon EC2):
Grant permissions to the IAM Users themselves, or
Assign a Launch Role to the Launch Constraint for the product
From Applying a Launch Constraint documentation:
Without a launch constraint, end users must launch and manage products with their own IAM credentials. To do so, they must have permissions for AWS CloudFormation, the AWS services used by the products, and AWS Service Catalog. By using a launch role, you can instead limit the end users' permissions to the minimum that they require.
Therefore, create a Launch Role with the necessary permissions to Launch an EC2 instance but only grant the users the minimum necessary permissions to launch the product from Service Catalog.