Cover of the book Symfony 5: The Fast Track

Symfony 5: The Fast Track is the best book to learn modern Symfony development, from zero to production. +300 pages in full color showing how to combine Symfony with Docker, APIs, queues & async tasks, Webpack, Single-Page Applications, etc.

Buy printed version

AWS S3 Resolver

1.0 version
Maintained

AWS S3 Resolver

The AwsS3Resolver resolver enables cache resolution using Amazon S3.

Dependencies

This cache resolver requires the aws-sdk-php library, which can be installed by executing the following command in your project directory:

1
$ composer require aws/aws-sdk-php

Note

This command requires that Composer is installed globally, as explained in their installation documentation.

Configuration

To begin, you must assign your AWS key, secret, bucket, and region to their respective parameters.

1
2
3
4
5
6
7
# app/config/config.yml or app/config/parameters.yml

parameters:
    amazon.s3.key:    "your-aws-key"
    amazon.s3.secret: "your-aws-secret"
    amazon.s3.bucket: "your-bucket.example.com"
    amazon.s3.region: "your-bucket-region"

Prerequisites

Create Resolver from a Factory

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# app/config/config.yml

liip_imagine:
    resolvers:
        profile_photos:
            aws_s3:
                bucket: "%amazon.s3.cache_bucket%"
                client_config:
                    credentials:
                        key:    "%amazon.s3.key%"
                        secret: "%amazon.s3.secret%"
                    region: "%amazon.s3.region%"
                get_options:
                    Scheme: https
                put_options:
                    CacheControl: "max-age=86400"

Tip

If using aws-sdk-php < 3.0.0, you must omit the credentials key and instead place the key and secret keys at the same level as region and bucket.

1
2
3
4
5
6
7
8
9
# app/config/services.yml

services:
    aws_s3:
        client_config:
            key:    "%amazon.s3.key%"
            secret: "%amazon.s3.secret%"
            region: "%amazon.s3.region%"
            bucket: "%amazon.s3.cache_bucket%"

Create Resolver as a Service

You have to set up the services required:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# app/config/services.yml

services:
    acme.amazon_s3:
        class: Aws\S3\S3Client
        factory_class: Aws\S3\S3Client
        factory_method: factory
        arguments:
            -
                credentials: { key: "%amazon.s3.key%", secret: "%amazon.s3.secret%" }
                region: "%amazon.s3.region%"

    acme.imagine.cache.resolver.amazon_s3:
        class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver
        arguments:
            - "@acme.amazon_s3"
            - "%amazon.s3.bucket%"
        tags:
            - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" }

Tip

If using aws-sdk-php < 3.0.0, you must omit the credentials key and instead place the key and secret keys at the same level as region and bucket.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# app/config/services.yml

services:
    acme.amazon_s3:
        # ...
        arguments:
            -
                key: "%amazon.s3.key%"
                secret: "%amazon.s3.secret%"
                region: "%amazon.s3.region%"

Usage

After configuring AwsS3Resolver, you can set it as the default cache resolver for LiipImagineBundle using the following configuration.

1
2
3
4
# app/config/config.yml

liip_imagine:
    cache: profile_photos

Usage on a Specific Filter

Alternatively, you can set AmazonS3Resolver as the cache resolver for a specific filter set using the following configuration.

1
2
3
4
5
6
7
8
9
# app/config/config.yml

liip_imagine:
    filter_sets:
        cache: ~
        my_thumb:
            cache: profile_photos
            filters:
                # the filter list

Tip

If you want to use other buckets for other images, simply alter the parameter names and create additional services.

Additional Options

You can use Cache and Proxy resolvers in chain with current. You just need to configure them with defined options.

1
2
3
4
5
6
7
8
9
# app/config/config.yml

liip_imagine:
    resolvers:
       profile_photos:
          aws_s3:
              #...
              proxies: ["http://one.domain.com", "http://two.domain.com"]
              cache: true

If enabled both first one will be Cache, then Proxy and after all process delegates to AwsS3 resolver.

Object GET Options

In order to make use of the object GET options, you can simply add a call to the service, to alter those options you need.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# app/config/services.yml

services:
    acme.imagine.cache.resolver.amazon_s3:
        class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver
        arguments:
            - "@acme.amazon_s3"
            - "%amazon_s3.bucket%"
        calls:
             # This calls $service->setGetOption('Scheme', 'https');
             - [ setGetOption, [ Scheme, https ] ]
        tags:
            - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" }

You can also use the constructor of the resolver to directly inject multiple options.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# app/config/services.yml

services:
    acme.imagine.cache.resolver.amazon_s3:
        class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver
        arguments:
            - "@acme.amazon_s3"
            - "%amazon_s3.bucket%"
            - "public-read" # Aws\S3\Enum\CannedAcl::PUBLIC_READ (default)
            - { Scheme: https }
        tags:
            - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" }

Object PUT Options

Similar to Object GET Options you can configure additional options to be passed to S3 when storing objects. This is useful, for example, to configure Cache- control headers returned when serving object from S3. See S3 SDK documentation for the list of available options.

Note, that the following options are configured automatically and will be ignored, even if you configure it via ObjectOptions:

  • ACL
  • Bucket
  • Key
  • Body
  • ContentType

In order to make use of the object PUT options, you can simply add a call to the service, to alter those options you need.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# app/config/services.yml

services:
    acme.imagine.cache.resolver.amazon_s3:
        class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver
        arguments:
            - "@acme.amazon_s3"
            - "%amazon_s3.bucket%"
        calls:
             # This calls $service->setPutOption('CacheControl', 'max-age=86400');
             - [ setPutOption, [ CacheControl, "max-age=86400" ] ]
        tags:
            - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" }

You can also use the constructor of the resolver to directly inject multiple options.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# app/config/services.yml

services:
    acme.imagine.cache.resolver.amazon_s3:
        class: Liip\ImagineBundle\Imagine\Cache\Resolver\AwsS3Resolver
        arguments:
            - "@acme.amazon_s3"
            - "%amazon_s3.bucket%"
            - "public-read" # Aws\S3\Enum\CannedAcl::PUBLIC_READ (default)
            - { Scheme: https }
            - { CacheControl: "max-age=86400" }
        tags:
            - { name: "liip_imagine.cache.resolver", resolver: "amazon_s3" }

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.