Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Configuring S3 Bucket & IAM User

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $10.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Friends, I think it's finally time to store the uploaded files up... in the cloud. We're going to use Amazon S3. But thanks to Flysystem, we could easily use a different service - they have a bunch of adapters. Google again for OneupFlysystemBundle... and click into their docs so we can see how to implement the s3 adapter. Search for S3 and... there it is.

Configuring the AWS S3 Adapter

The first thing we need is this aws/aws-sdk-php package. Copy that, move over to your terminal and run:

composer require "aws/aws-sdk-php:^3.87"

Creating the S3 Bucket

While we're waiting for that, let's create the S3 bucket that will store our stuff! I'm already logged into the S3 section of AWS. Click "Create bucket" and let's call it sfcasts-spacebar. Choose whatever region makes sense for you - but remember that, because you'll need it later.

On the next screen, if you need encryption or logging or any of these things, check them. But we'll just click next again to get to permissions. There are a few things we need to do here. First, uncheck the two top boxes for "Block new public ACLs" and "Remove public access granted through public ACLs". By unchecking these boxes, we can now have private files and public files all in the same bucket. Click "Next" again and then "Create bucket".

IAM Permissions

Awesome! Bucket done! To be able to actually access this bucket... I'm going to open an new tab for the IAM service. Click "Users" and add a new user. Let's call it: sfcasts-spacebar-s3-access.

Okay. Check yes for "programmatic access", but don't check console access. This user will exist solely so we can use its credentials in our app to talk to S3.

For permissions, this is always the tricky part, at least for me. There are a lot of existing "policies" that can grant different permissions to different services... I'm going to open another tab to IAM and click to create a new policy.

There's a builder to help create the policy... or you can click the JSON tab to do it yourself. So... what do we put here? Fortunately, Flysystem has our back. In its docs for AWS S3, scroll down and... nice! It gives us the IAM permissions we need! Copy that, go back, and paste. Tweak the bucket name to be our bucket name. Let's see... it's sfcasts-spacebar. Back on the policy, paste that in both spots.

{
    "Version": "2012-10-17",
    "Statement": [{
        "Sid": "Stmt1420044805001",
        "Effect": "Allow",
        "Action": [
            "s3:ListBucket",
            "s3:GetObject",
            "s3:GetObjectAcl",
            "s3:PutObject",
            "s3:PutObjectAcl",
            "s3:ReplicateObject",
            "s3:DeleteObject"
        ],
        "Resource": [
            "arn:aws:s3:::your-bucket-name",
            "arn:aws:s3:::your-bucket-name/*"
        ]
    }]
}

This policy basically gives the new user full access to this specific bucket. Click "Review policy" and give it a name, how about sfcasts-spacebar-full-s3-bucket-access. Ok, create policy!

With that done, close that tab and go back to the original IAM tab where we're creating our new user. Click the little refresh button and search for sfcasts. The second policy was from me testing this earlier. Check the first box and hit "Next". Skip the tags... looks good... and create user!

Congrats! The hardest part is over! This gives us two things we need: a key and a secret. Next: let's set these as environment variables in our app and configure Flysystem to talk to S3!

Leave a comment!

5
Login or Register to join the conversation
Cameron Avatar
Cameron Avatar Cameron | posted 1 year ago

there's no AWS policy script in the "script" section sadly (for easy copy paste), and the flysystem website took it down - so it needs to be manually typed out.

Reply
Cameron Avatar

FYR if anyone who needs it:


{
"Version": "2012-10-17",
"Statement": [{
"Sid": "Stmt1420044805001",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:ReplicateObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
}]
}
Reply

Thank you Fox C. !
You're right, a code block would be convenient here

Cheers!

Reply
Sylvain C. Avatar
Sylvain C. Avatar Sylvain C. | posted 1 year ago

Hey Team ! thanks for this amazing tutorial.

Can you explain in few words the privacy access to bucket ?

I try to understand but it's my first time in this world.

When Ryan uncheck the two first items, it's because he only want access to the files only on his own website ? Not outside ?

How can I make my files accessible only to my logged in users?

Thanks again and again !!!

Reply

Hey Sylvain C.!

Yes... this stuff can be tricky! Those 2 checkboxes are around 1:30 in the video (to help anyone else).

Here's how this works:

When you upload a file to S3, you can choose the exact permissions that you want on that file. This is called the ACL for that "object". You could make a file "public" (meaning that if you know the URL to that file, then anyone can access it) or "private" (meaning that if you know the URL to that file, then you still CANNOT access it, unless you are authenticated in some way - more on that in a minute).

The checkboxes activated a setting on the "bucket" level. If I had KEPT those both checked, and then I tried to upload a new file with "public ACL", I believe S3 would have rejected it because that public ACL would have violated my bucket settings.

The more important point is that, when you upload a file, you can set each file to be "public" or "private". If a file is public, it's easy! You could render a link to that file on your site and everything would work :).

> How can I make my files accessible only to my logged in users?

For this, you would upload your files and make them "private". Then, when you need to send/show a link to a user for that file, you generate a temporary "signed url" - we talk about that here: https://symfonycasts.com/sc...

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial is built on Symfony 4 but works great in Symfony 5!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.1.3",
        "ext-iconv": "*",
        "aws/aws-sdk-php": "^3.87", // 3.87.10
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "knplabs/knp-markdown-bundle": "^1.7", // 1.7.1
        "knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
        "knplabs/knp-time-bundle": "^1.8", // 1.9.0
        "league/flysystem-aws-s3-v3": "^1.0", // 1.0.22
        "league/flysystem-cached-adapter": "^1.0", // 1.0.9
        "liip/imagine-bundle": "^2.1", // 2.1.0
        "nexylan/slack-bundle": "^2.0,<2.2.0", // v2.1.0
        "oneup/flysystem-bundle": "^3.0", // 3.0.3
        "php-http/guzzle6-adapter": "^1.1", // v1.1.1
        "sensio/framework-extra-bundle": "^5.1", // v5.2.4
        "stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
        "symfony/asset": "^4.0", // v4.2.3
        "symfony/console": "^4.0", // v4.2.3
        "symfony/flex": "^1.9", // v1.17.6
        "symfony/form": "^4.0", // v4.2.3
        "symfony/framework-bundle": "^4.0", // v4.2.3
        "symfony/orm-pack": "^1.0", // v1.0.6
        "symfony/security-bundle": "^4.0", // v4.2.3
        "symfony/serializer-pack": "^1.0", // v1.0.2
        "symfony/twig-bundle": "^4.0", // v4.2.3
        "symfony/validator": "^4.0", // v4.2.3
        "symfony/web-server-bundle": "^4.0", // v4.2.3
        "symfony/yaml": "^4.0", // v4.2.3
        "twig/extensions": "^1.5" // v1.5.4
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.0", // 3.1.0
        "easycorp/easy-log-handler": "^1.0.2", // v1.0.7
        "fzaninotto/faker": "^1.7", // v1.8.0
        "symfony/debug-bundle": "^3.3|^4.0", // v4.2.3
        "symfony/dotenv": "^4.0", // v4.2.3
        "symfony/maker-bundle": "^1.0", // v1.11.3
        "symfony/monolog-bundle": "^3.0", // v3.3.1
        "symfony/phpunit-bridge": "^3.3|^4.0", // v4.2.3
        "symfony/profiler-pack": "^1.0", // v1.0.4
        "symfony/var-dumper": "^3.3|^4.0" // v4.2.3
    }
}