Thomas Kainrad
Thomas Kainrad

Reputation: 2820

Allow access to S3 Bucket from all EC2 instances of specific Account

Is there any way to allow all instances created by a specific AWS account access to an S3 bucket?

I would like to provide data that should be very simple for clients to download to their instances. Ideally, automatically via the post_install script option of AWS ParallelCluster.

However, it seems like this requires a lot of setup, as is described in this tutorial by AWS:
https://aws.amazon.com/premiumsupport/knowledge-center/s3-instance-access-bucket/

This is not feasible for me. Clients should not have to create IAM roles.

The best I came up with at the moment is allowing S3 bucket access to a specific AWS account and then working with access keys:

export AWS_ACCESS_KEY_ID=<key-id>
export AWS_SECRETE_ACCESS_KEY=<secret-key>

aws s3 cp s3://<bucket> . --recursive

Unfortunately, this is also not ideal as I would like to provide ready-to-use AWS Parallelcluster post_install scripts. These scripts should automatically download the required data on cluster startup.

Upvotes: 0

Views: 1422

Answers (2)

John Rotenstein
John Rotenstein

Reputation: 269320

You say "Clients should not have to create IAM roles". This is perfectly correct.

I presume that you are creating the instances for use by the clients. If so, then you should create an IAM Role that has access to the desired bucket.

Then, when you create an Amazon EC2 instance for your clients, associate the IAM Role to the instance. Your clients will then be able to use the AWS Command-Line Interface (CLI) to access the S3 bucket (list, upload, download, or whatever permissions you put into the IAM Role).

If you want the data to be automatically downloaded when you first create their instance, then you can add User Data script that will execute when the instance starts. This can download the files from S3 to the instance.

Upvotes: 0

Moe
Moe

Reputation: 2842

Is there any way to allow all instances created by a specific AWS account access to an S3 bucket?

Yes. It's a 2 step process. In summary:
1) On your side, the bucket must trust the account id of the other accounts that will access it, and you must decide which calls you will allow.
2) On the other accounts that will access the bucket, the instances must be authorised to run AWS API calls on your bucket using IAM policies.

In more detail:

Step 1: let's work through this and break it down. On your bucket, you'll need to configure a bucket policy like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "111",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::ACCOUNT_ID_TO_TRUST:root"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME_HERE/*"
        }
    ]
}

You can find more examples of bucket policies in the AWS documentation here.

WARNING 1: "arn:aws:iam::ACCOUNT_ID:root" will trust everything that has permissions to connect to your bucket on the other AWS account. This shouldn't be a problem for what you're trying to do, but it's best you completely understand how this policy works to prevent any accidents.

WARNING 2: Do not grant s3:* - you will need to scope down the permissions to actions such as s3:GetObject etc. There is a website to help you generate these policies here. s3:* will contain delete permissions which if used incorrectly could result in nasty surprises.

Now, once that's done, great work - that's things on your end covered.

Step 2: The other accounts that want to read the data will have to assign an instance role to the ec2 instances they launch and that role will need a policy attached to it granting access to your bucket. Those instances can then run AWS CLI commands on your bucket, provided your bucket policy authorises the call on your side and the instance policy authorises the call on their side. The policy that needs to be attached to the instance role should look something like this:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME_HERE/*"
    }
  ]
}

Keep in mind, just because this policy grants s3:* it doesn't mean they can do anything on your bucket, not unless you have s3:* in your bucket policy. Actions of this policy will be limited to whatever you've scoped the permissions to in your bucket policy.

This is not feasible for me. Clients should not have to create IAM roles.

If they have an AWS account it's up to them on how they choose to access the bucket as long as you define a bucket policy that trusts their account the rest is on them. They can create an ec2 instance role and grant it permissions to your bucket, or an IAM User and grant it access to your bucket. It doesn't matter.

The best I came up with at the moment is allowing S3 bucket access to a specific AWS account and then working with access keys:

If the code will run on an ec2 instance, it's bad practice to use access keys and instead should use an ec2 instance role.

Ideally, automatically via CloudFormation on instance startup.

I think you mean via instance userdata, which you can define through CloudFormation.

Upvotes: 2

Related Questions