By default every elastic beanstalk application has an associated S3 bucket for storing application versions, rotated logs (enable it) and temporary configuration. Multiple elastic beanstalks in a same region share the same S3 bucket. More on it in https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.S3.html

Push rotated logs to S3

To persist logs, you can configure your environment to publish logs to Amazon S3 automatically after they are rotated.
To enable log rotation to Amazon S3, follow the procedure in Configuring instance log viewing

Go to your eb environment -> configuration -> scroll down to software and click on edit.
In the S3 log storage part, choose Rotate logs to enable uploading rotated logs to S3.

s3 rotate logs

Push arbitrary data folder to S3

Maybe you want to push something else to S3, like a static data folder.

This solution explains my configuration for eb node.js application.

When you connect to your ec2 instance, your app should be located in /var/app/current.

And elastic beanstalk ec2 instances have aws cli installed by default.

1. Create bucket

Go to S3, create a new bucket, type unique name for your bucket and click on Create bucket.

2. Find Role ARN

Next step is configuring permissions for the created bucket. I want to permit elastic beanstalk ec2 to crud the s3 bucket. For that reason, I first need to know the unique identifier of elastic beanstalk ec2 role, also known as ARN (amazon resource name). To find out the fully qualified id of the required role, go to IAM -> Roles -> Find aws-elasticbeanstalk-ec2-role -> Click on it and copy ARN.

3. Update bucket permissions

Without appropriate permission, bucket returns access denied for any kind of request. To stop getting access denied, s3 bucket needs to allow access to ec2 elastic beanstalk role.

To enable pushing to your bucket, go to s3, click on your bucket, permissions and then edit policy.

Copy below contents, replacing YOUR_BUCKET with your bucket name.

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "yoursid",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::12121212:role/aws-elasticbeanstalk-ec2-role"
            },
            "Action": [
               "s3:ListBucket",       
               "s3:PutObject",
               "s3:PutObjectAcl",
               "s3:GetObject",
               "s3:GetObjectAcl",
               "s3:DeleteObject"
            ],
            "Resource": ["arn:aws:s3:::YOUR_BUCKET", "arn:aws:s3:::YOUR_BUCKET/*"]
        }
    ]
}

4. Perform S3 sync

You push to s3 inside the eb ec2 instance with:

aws s3 sync .next/static s3://YOUR_BUCKET/_next/static

To pull from s3 bucket:

aws s3 cp s3://YOUR_BUCKET/_next/static .next/static --recursive

If your eb instance hosts a nodejs app, you can for example add a prestart hook:

package.json

{
   "prestart": "aws s3 sync .next/static s3://MY_BUCKET/_next/static",
   "start": "NODE_ENV=production node server.js",
}