赞
踩
Assets like images, PDFs, and other files are often an important part of the “content” that a Content Management System handles.
Although this article was written with Craft CMS in mind, the vast majority of the article applies generically to any CMS or website.
Craft CMS has some fantastic native handling of said assets, which by default are stored in folders on your server.
However, it can be convenient to use a cloud-based storage system like Amazon Web Services (AWS) Simple Storage Service (S3):
There are other advantages as well, but we’ll just assume you’re on-board, and get right into how to set it up.
S3 stores files in “buckets”, and while you can serve assets directly from an S3 bucket, I’d strongly recommend against it.
Don’t serve assets directly from S3 buckets
S3 buckets are intended for asset storage, not serving assets. It’ll work, but you’ll only be serving them out of one geographic region (wherever your S3 bucket was created), and it really wasn’t designed to for that.
Instead, use AWS CloudFront as your Content Delivery Network (CDN) that actually serves up your assets.
Here’s what it looks like conceptually:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KjGgikUB-1669738403971)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQAAAQABAAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAANABADASIAAhEBAxEB%2F8QAFgABAQEAAAAAAAAAAAAAAAAAAwAG%2F8QAIBAAAgIBBAMBAAAAAAAAAAAAAQIDBAAREjFRExQhcf%2FEABUBAQEAAAAAAAAAAAAAAAAAAAAB%2F8QAGhEAAgMBAQAAAAAAAAAAAAAAAQIAETESIf%2FaAAwDAQACEQMRAD8A1lxoblSREsqgVgGYHg9ZQv6lWvGh84Ztu%2FcBz%2B4y0ayo6rCoVzqw7OFZrqqwLGEVVkHwrrlJN%2BZCIt9Ns%2F%2FZ)]
AWS S3 + CloudFront Overview
The idea is that when a person loads one of your web pages with an image on it, the image will point to a CloudFront URL.
If that image is in the cache, it’ll return it from a CDN Edge server that is geographically near the person loading the page. This makes it quick, with low latency.
If the image isn’t in the cache, CloudFront pulls it from your S3 bucket, returns it to the person, and propagates the image to the CDN Edge locations.
S3 Buckets shouldn’t be publicly accessible
The rule of thumb here is that S3 buckets aren’t publicly accessible. Instead, CloudFront is given permission to pull assets from the S3 buckets.
That said, let’s get into setting it all up.
If you don’t already have an AWS account, you’re going to need one. Go to your AWS Console and either log in to your account, or create a new account.
If you want the billing to go directly to your clients, you can either create an AWS account for them, or use their existing account.
If you factor in the relatively low cost of S3 into your maintenance contracts or the like, you can just have one account for all of your clients.
If you don’t have one already, you should also set up an admin account for AWS now.
Now that we have an AWS account, the first thing we’re going to do is set up our S3 bucket. We’re going to use kebab-case for all of our AWS entity names, and we’ll use the format:
project-name + - + descriptor
We’ll be setting up S3 + CloudFront for devMode.fm, so the project name is devmode, and the bucket name is devmode-bucket.
In your AWS Console, click on Services → S3 → + Create Bucket. Fill in the name of the bucket, and click through to the end (we won’t be changing any settings from the default other than the name):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pAgYlftu-1669738403978)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAALABADASIAAhEBAxEB%2F8QAFgABAQEAAAAAAAAAAAAAAAAAAgAD%2F8QAIBAAAQMCBwAAAAAAAAAAAAAAAQACAwRBERITITFRgf%2FEABQBAQAAAAAAAAAAAAAAAAAAAAP%2FxAAXEQADAQAAAAAAAAAAAAAAAAAAARJR%2F9oADAMBAAIRAxEAPwDF9VMN9SyLauYuGLzz0hYKaBn9CanoMrD%2F2Q%3D%3D)]
Creating an S3 bucket
Note that for Permissions, it’s set to Block *all* public access. As discussed above, our S3 bucket will be private, and the CloudFront distribution will be public.
For most projects, I create one bucket, and use sub-folders in the bucket for different Asset Volumes. You can certainly also create more than one bucket if that’ll work better for you.
Next we’ll set up a custom Identity and Access Management (IAM) policy to control access. IAM policies can be attached to any AWS object, and they control who can access what, with some fairly fine-grained permissions.
We’re using a custom policy because we want to grant as little access as possible, but still have it work correctly.
This isn’t a fancy watch. We don’t add complications just because they look cool
From your AWS Console, click on Services → IAM → Policies → Create Policy.
Click on the JSON tab, and then paste this in:
custom policy
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "acm:ListCertificates", "cloudfront:GetDistribution", "cloudfront:GetStreamingDistribution", "cloudfront:GetDistributionConfig", "cloudfront:ListDistributions", "cloudfront:ListCloudFrontOriginAccessIdentities", "cloudfront:CreateInvalidation", "cloudfront:GetInvalidation", "cloudfront:ListInvalidations", "elasticloadbalancing:DescribeLoadBalancers", "iam:ListServerCertificates", "sns:ListSubscriptionsByTopic", "sns:ListTopics", "waf:GetWebACL", "waf:ListWebACLs" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:GetBucketLocation", "s3:ListAllMyBuckets" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::REPLACE-WITH-BUCKET-NAME" ] }, { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "arn:aws:s3:::REPLACE-WITH-BUCKET-NAME/*" ] } ] }
custom policy
Make sure you replace REPLACE-WITH-BUCKET-NAME with the name of the bucket we created in Step 2 (in our case devmode-bucket), in both places.
Then click on Review Policy, and give your policy a name (in our case devmode-policy) and description, then click on Create Policy:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCTGlRcL-1669738403989)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAALABADASIAAhEBAxEB%2F8QAFgABAQEAAAAAAAAAAAAAAAAAAQIG%2F8QAHBAAAgICAwAAAAAAAAAAAAAAAQIAEQMhEhNh%2F8QAFAEBAAAAAAAAAAAAAAAAAAAAAP%2FEABQRAQAAAAAAAAAAAAAAAAAAAAD%2F2gAMAwEAAhEDEQA%2FAN2zcWoXHsB0VO%2FInYBkZmKJamjA%2F9k%3D)]
Creating an IAM policy
Instead of attaching the IAM policy we created to a bucket or a user, we’re going to create a group, and attach it to the group.
The IAM policy gets attached to the group
We’re doing this because it makes it trivial to move users in and out of the group, and the group is what is controlling access permissions.
You also then won’t be out of luck if you somehow lose the user credentials, you can just create a new user and assign it to the group.
From your AWS Console, click on Services → IAM → Groups → Create New Group, and give your group a name (in our case devmode-group).
At the Attach Policy screen, search for the policy we created in Step 3, and check it and click Next Step:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ap9EFMJr-1669738403991)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAAKABADASIAAhEBAxEB%2F8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEDBv%2FEABkQAQEBAAMAAAAAAAAAAAAAAAEAAxJRYf%2FEABQBAQAAAAAAAAAAAAAAAAAAAAD%2FxAAUEQEAAAAAAAAAAAAAAAAAAAAA%2F9oADAMBAAIRAxEAPwDfcTqcU91MlFHyD%2F%2FZ)]
Creating a group
Then click on Create Group to create your new group.
Next we’re going to create a user, and assign it to the group we just created. The user we create will be a generic project user, rather than an actual person.
From your AWS Console, click on Services → IAM → Users → Add user, and give your user a name (in our case devmode-user). Also check only the Programatic access checkbox under Access type:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZioFDGZF-1669738403993)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAANABADASIAAhEBAxEB%2F8QAFgABAQEAAAAAAAAAAAAAAAAAAgEG%2F8QAGhABAAIDAQAAAAAAAAAAAAAAAQACESFBMf%2FEABQBAQAAAAAAAAAAAAAAAAAAAAD%2FxAAUEQEAAAAAAAAAAAAAAAAAAAAA%2F9oADAMBAAIRAxEAPwDdq044zzcVUXzcckD%2F2Q%3D%3D)]
Creating a user: details
This ensures that using these credentials, there’s no AWS Management Console access. For that, you’ll use your regular admin account & credentials.
Click on Next: Permissions, then add the user to the group we created in Step 4:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8hiE5LvU-1669738404009)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAANABADASIAAhEBAxEB%2F8QAFgABAQEAAAAAAAAAAAAAAAAAAQMG%2F8QAGxABAAMBAAMAAAAAAAAAAAAAAQACESExUYH%2FxAAUAQEAAAAAAAAAAAAAAAAAAAAA%2F8QAFBEBAAAAAAAAAAAAAAAAAAAAAP%2FaAAwDAQACEQMRAD8A3NVN21vPqJc49fkoW1TIwP%2FZ)]
Creating a user: permissions
Then click on Next: Tags (we don’t set any tags here), then click on Next: Review:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o5JJki9R-1669738404012)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAANABADASIAAhEBAxEB%2F8QAFgABAQEAAAAAAAAAAAAAAAAAAgAG%2F8QAGxAAAwACAwAAAAAAAAAAAAAAAAERITFBcYH%2FxAAUAQEAAAAAAAAAAAAAAAAAAAAA%2F8QAFBEBAAAAAAAAAAAAAAAAAAAAAP%2FaAAwDAQACEQMRAD8A3absVnQsc1%2BC0QH%2F2Q%3D%3D)]
Creating a user: review
Then click on Create User. You’ll be taken to a screen where you can see your Access key ID and Secret access key:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ia2gZTfC-1669738404018)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAAGABADASIAAhEBAxEB%2F8QAFgABAQEAAAAAAAAAAAAAAAAAAAIG%2F8QAGxAAAgIDAQAAAAAAAAAAAAAAAQIAAxEiMSH%2FxAAUAQEAAAAAAAAAAAAAAAAAAAAA%2F8QAFBEBAAAAAAAAAAAAAAAAAAAAAP%2FaAAwDAQACEQMRAD8A3IJydiPeSEvV7Gr2JU4OeRED%2F9k%3D)]
Creating a user: credentials
Click on Download .csv to download a CSV file that has your credentials in it. You will need these credentials to access your S3 bucket, and this is the only time you’ll be able to retrieve them.**
**
Now we need to create a CloudFront Distribution that will be acting as our CDN, and actually delivering our assets to the users who request them.
From your AWS Console, click on Services → CloudFront → Create Distribution, and click on the Get Started button below the Web heading.
Alter the following settings:
Origin domain — choose the origin for the S3 bucket we created in Step 2
S3 bucket access
→
select
Yes use OAI (bucket can restrict access to only CloudFront)
Bucket policy
→
Compress object automatically
Viewer Protocol Policy — Redirect HTTP to HTTPS
Allowed HTTP Methods — GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Cache key and origin requests
→
select
Cache policy and origin request policy
(recommended)
Cache policy
→
N.B.: For your bucket to work with CloudFront, the name must conform to DNS naming requirements. For Regions launched in 2019 or later, that format is: bucket-name.s3.region.amazonaws.com
Here’s a full screenshot for the settings we’re using for devMode.fm:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jQcHpd9k-1669738404024)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQEAYABgAAD%2F%2FgA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2ODApLCBxdWFsaXR5ID0gNTAK%2F9sAQwAQCwwODAoQDg0OEhEQExgoGhgWFhgxIyUdKDozPTw5Mzg3QEhcTkBEV0U3OFBtUVdfYmdoZz5NcXlwZHhcZWdj%2F9sAQwEREhIYFRgvGhovY0I4QmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nj%2F8AAEQgALQAQAwEiAAIRAQMRAf%2FEAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC%2F%2FEALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29%2Fj5%2Bv%2FEAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC%2F%2FEALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5%2Bjp6vLz9PX29%2Fj5%2Bv%2FaAAwDAQACEQMRAD8A7mNQCcKv4DmpNo9KiVfmOPX1%2FwDr1NzjqKAGRnqAD%2BdP59P1pkTdQT0PFSHpQBChO4jI69OalFMReSePyp9AH%2F%2FZ)]
Creating a CloudFront Distribution
Then click on Create Distribution.
You’ll be taken to a strange “CloudFront Private Content Getting Started” page; this isn’t an error page, and there aren’t any more steps to take.
We just need to grab a couple of settings from our newly created CloudFront distribution.
From your AWS Console, click on Services → CloudFront → then click on the CloudFront distribution we just created:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dVPtpKKF-1669738404028)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAAKABADASIAAhEBAxEB%2F8QAFgABAQEAAAAAAAAAAAAAAAAAAgMG%2F8QAHhAAAQQCAwEAAAAAAAAAAAAAAQACAxESIQQyYXH%2FxAAUAQEAAAAAAAAAAAAAAAAAAAAA%2F8QAFBEBAAAAAAAAAAAAAAAAAAAAAP%2FaAAwDAQACEQMRAD8A3E5EeOJok7KcdOFh2XtockbZ9Vm9Qg%2F%2F2Q%3D%3D)]
CloudFront Distribution Settings
We’re going to need the Distribution ID and Domain Name settings, so copy them down somewhere.
We’re all done with the AWS S3 + CloudFront setup!
Next we need to configure Craft CMS to use our new S3 bucket setup. If you’re using something other than Craft CMS, you’ll need to fill in the analogous settings.
The key point to remember is that the public URL will be our CloudFront distribution URL (in our case https://dnzwsrj1eic0g.cloudfront.net); make sure you add the https:// protocol to it.
First, we’ll need to install the first-party Amazon S3 plugin.
Next we’ll need to set up our Asset Volumes. I use Environment Variables in my .env file to store all of my secrets, so they aren’t in the database, and the don’t end up in Git via Project Config:
.env file environment variables
# S3 settings
S3_KEY_ID=XXXXXXXXXX
S3_SECRET=XXXXXXXXXX
S3_BUCKET=devmode-bucket
S3_REGION=us-east-2
# CloudFront settings
CLOUDFRONT_URL=https://dnzwsrj1eic0g.cloudfront.net
CLOUDFRONT_DISTRIBUTION_ID=E17SKV1U1OTZKW
CLOUDFRONT_PATH_PREFIX=
.env file environment variables
In the Craft CMS CP, go to Settings → Assets → New volume, and fill in the volume settings as shown:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0aOZa6xg-1669738404033)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAHAAcAAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAAbABADASIAAhEBAxEB%2F8QAFwABAAMAAAAAAAAAAAAAAAAAAgEDBv%2FEABwQAAICAgMAAAAAAAAAAAAAAAABAgMRMTJBgf%2FEABQBAQAAAAAAAAAAAAAAAAAAAAD%2FxAAUEQEAAAAAAAAAAAAAAAAAAAAA%2F9oADAMBAAIRAxEAPwDdQrjjQnVFrDRMOOxIAQ8GV19jA%2F%2FZ)]
Craft CMS Asset Volume settings
Note that Bucket has been set to Manual so we can use our environment variables, and we’ve manually added episodes to Subfolder.
Also note that we have turned Make Uploads Public OFF. If you enable it, it will set a manual ACL on your S3 assets to allow public access, which isn’t what we want. We want private S3 assets with public access through CloudFront only
If you’re using Project Config, your project.yaml will end up looking like the following:
project.yaml
e69c8edb-d562-4367-9a05-91a6fd2c7d99: name: 'Devmode Episodes' handle: devmodeEpisodes type: craft\awss3\Volume hasUrls: true url: $CLOUDFRONT_URL settings: subfolder: episodes keyId: $S3_KEY_ID secret: $S3_SECRET bucketSelectionMode: manual bucket: $S3_BUCKET region: $S3_REGION expires: '3 months' makeUploadsPublic: '' storageClass: '' cfDistributionId: $CLOUDFRONT_DISTRIBUTION_ID cfPrefix: $CLOUDFRONT_PATH_PREFIX autoFocalPoint: '' sortOrder: 4
project.yaml
Look, mah, no secrets!
Then we can upload an image to our new Asset Volume:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v0fiIRer-1669738404045)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAALABADASIAAhEBAxEB%2F8QAFgABAQEAAAAAAAAAAAAAAAAABQQH%2F8QAIxAAAgIBAgYDAAAAAAAAAAAAAQIDBAUAEgYREyFhcRRBUf%2FEABUBAQEAAAAAAAAAAAAAAAAAAAAB%2F8QAFREBAQAAAAAAAAAAAAAAAAAAAAH%2F2gAMAwEAAhEDEQA%2FAEeC1%2BZj5DOkcuwqqlgOw2%2BtN5KjAMbaIgiBETnmFH4fGs1wubyNGu6VbJjUkEjYp%2BvI1bY4mzEleRHuEqykEdNe45etWj%2F%2F2Q%3D%3D)]
Uploaded Image in the Craft CMS CP
And we can verify that the image is indeed coming from our CloudFront distribution URL:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nz8YSmL4-1669738404049)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQIAOQA5AAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAANABADASIAAhEBAxEB%2F8QAFwAAAwEAAAAAAAAAAAAAAAAAAQIFBv%2FEACEQAAIBBAICAwAAAAAAAAAAAAIDAQAEESEFBhJBEyIx%2F8QAFAEBAAAAAAAAAAAAAAAAAAAAAP%2FEABQRAQAAAAAAAAAAAAAAAAAAAAD%2F2gAMAwEAAhEDEQA%2FAJ3XXOu7eYZiRXgYkVjqMe9U3ZXMtLZfwNEgcOC8kjExrfqs%2FwAfy7rBRrVGjn7b%2FaPIcu6%2FStbRGBXGBxQf%2F9k%3D)]
Uploaded Image CloudFront distribution URL
That’s all you need to start enjoying the benefits of cloud storage in S3, and CloudFront as a global Content Delivery Network.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QWvRKv9E-1669738404053)(data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQAAAQABAAD%2F2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P%2F2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P%2FwAARCAAJABADASIAAhEBAxEB%2F8QAFQABAQAAAAAAAAAAAAAAAAAAAgX%2FxAAjEAACAgEACwAAAAAAAAAAAAABAwIEABESExQiMTJBUWFx%2F8QAFQEBAQAAAAAAAAAAAAAAAAAABAX%2FxAAcEQABBAMBAAAAAAAAAAAAAAARAAECEwMEIeH%2F2gAMAwEAAhEDEQA%2FAKD1XC5a6yxokDrSPKPg4aqrh229rEBE8PvLKu2G10n6MkUwbXI76ntllaCv%2F9k%3D)]
This whole manual setup can be automated via an AWS CloudFormation stack… but that’s left as an exercise for the reader (or maybe another article).
Thanks to all around great guy Jonathan Melville of CodeMDD.io for this help with this article.
Happy uploading!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。