$30 off During Our Annual Pro Sale. View Details »

AWS for Artisans

AWS for Artisans

The power of the AWS cloud is available for Laravel Artisans. In this presentation I'll give an introduction to AWS and show how you can build a Laravel application using the AWS SDK for PHP and deploy it to AWS Elastic Beanstalk.

Jeremy Lindblom

May 15, 2014
Tweet

More Decks by Jeremy Lindblom

Other Decks in Programming

Transcript

  1. aws for
    artisans
    by @jeremeamia
    #aws #laracon

    View Slide

  2. Hi, I’m Jeremy.
    or @jeremeamia
    Seattle PHP User Group
    or @seaphp
    AWS SDK for PHP
    @awsforphp

    View Slide

  3. •  aws/aws-­‐sdk-­‐php  
    Used in Laravel Queues for SQS driver.
    •  aws/aws-­‐sdk-­‐php-­‐laravel  
    AWS Service Provider for Laravel.
    •  jeremeamia/super_closure  
    Allows you to serialize/queue closures.

    View Slide

  4. View Slide

  5. View Slide

  6. “The Cloud”

    View Slide

  7. The Clooouuud

    View Slide

  8. The term
    "Cloud Computing" refers
    to the on-demand delivery
    of IT resources via the Internet
    with pay-as-you-go pricing.

    View Slide

  9. IT Resources?
    Servers • Computing Nodes
    Distributed Queues • Databases
    Push Notifications
    File Storage • Load Balancers
    Content Delivery Networks
    Cache Clusters • more…

    View Slide

  10. AWS services each have an API,
    so you can control your resources
    through programs and scripts.

    View Slide

  11. So let's provision a web server from
    PHP by using the AWS SDK for PHP
    to talk to the Amazon EC2 API
    Amazon  EC2  

    View Slide

  12. View Slide

  13. View Slide

  14. With the
    AWS Service Provider for Laravel:

    View Slide

  15. View Slide

  16. View Slide

  17. View Slide

  18. STORAGE  
    VOLUMES  
    KEY  PAIRS  
    STATIC  IPs  
    FIREWALLS  

    View Slide

  19. Amazon  EC2  

    View Slide

  20. Amazon  EC2  
    Amazon  S3  
    Amazon  RDS  
    Amazon  SQS  
    Elas?c  
    Transcoder  

    View Slide

  21. Amazon  S3  
    Amazon  SES  
    Amazon  SimpleDB  
    Amazon  SNS  
    Amazon  SQS  
    Amazon  SWF  
    Amazon  VPC  
    Auto  Scaling  
    AWS  CloudHSM  
    AWS  Data  Pipeline  
    AWS  Elas?c  Beanstalk  
    AWS  Import/Export  
    AWS  OpsWorks  
    AWS  Marketplace  
    AWS  Storage  Gateway  
    AWS  Support  
    Elas?c  Load  Balancing  
    Amazon  CloudForma?on  
    Amazon  CloudFront  
    Amazon  CloudSearch  
    Amazon  CloudWatch  
    Amazon  Direct  Connect  
    Amazon  DynamoDB  
    Amazon  EBS  
    Amazon  EC2  
    Amazon  Elas?Cache  
    Amazon  Elas?c  Transcoder  
    Amazon  EMR  
    Amazon  Glacier  
    Amazon  IAM  
    Amazon  Mechanical  Turk  
    Amazon  RDS  
    Amazon  RedshiR  
    Amazon  Route53  

    View Slide

  22. PHP • Java • Python • .NET • Ruby
    JavaScript • Node • iOS • Android
    SDKs
    AWS CLI • Visual Studio Plugin
    Eclipse Plugin • PowerShell
    Management Console • iOS App
    Tools
    https://github.com/aws
    AWS SDKs & Tools

    View Slide

  23. Hundreds of Thousands of
    Customers in 190 Countries

    View Slide

  24. Let’s Build Something!

    View Slide

  25. Funny Face App

    View Slide

  26. Funny Face App

    View Slide

  27. Funny Face App
    Level #1
    Wherein we setup our dependencies

    View Slide

  28. Add the AWS SDK for PHP
    In your composer.json:
    {  
       ...  
       "aws/aws-­‐sdk-­‐php":  "~2.6.2",  
       "aws/aws-­‐sdk-­‐php-­‐laravel":  "~1.1",  
       ...  
    }  

    View Slide

  29. Add the AWS Service Provider
    In your app/config/app.php:
       'providers'  =>  array(  
           ...  
           'Aws\Laravel\AwsServiceProvider',  
       )  
         
       'aliases'  =>  array(  
           ...  
           'Aws\Laravel\AwsFacade',  
       )  

    View Slide

  30. Setup AWS Credentials
    In your ~/.aws/credentials file:  
     
    [default]  
    aws_access_key_id=AKIAEXAMPLE3A…  
    aws_secret_access_key=wFooBarTn…  
    Available in aws/aws-­‐sdk-­‐php:>=2.6.2  
     

    View Slide

  31. Setup AWS Resources
    $  php  artisan  funnyface:setup  
    Config  file  written  to  app/config/funnyfaces.php.  
    Creating  S3  bucket  "funnyfaces-­‐xkl9syjmwkhm"…  
    Done.  
    Creating  DynamoDB  table  "funnyfaces-­‐xkl9syjmwkhm"…  
    Done.  
    The  Funny  Face  App  is  setup.  
    Amazon  
    S3  
    Amazon  
    DynamoDB  

    View Slide

  32. Setup S3 Bucket
    function  createBucket(S3Client  $s3,  $bucket)  
    {  
     if  (!$s3-­‐>doesBucketExist($bucket))  {  
       $s3-­‐>createBucket(['Bucket'  =>  $bucket]);  
       $s3-­‐>waitUntil('BucketExists',  [  
         'Bucket'  =>  $bucket  
       ]);  
     }  
    }  

    View Slide

  33. Setup S3 Bucket
    function  createBucket(S3Client  $s3,  $bucket)  
    {  
     if  (!$s3-­‐>doesBucketExist($bucket))  {  
       $s3-­‐>createBucket(['Bucket'  =>  $bucket]);  
       $s3-­‐>waitUntil('BucketExists',  [  
         'Bucket'  =>  $bucket  
       ]);  
     }  
    }  
     
     
     if  (!$s3-­‐>doesBucketExist($bucket))  {  
    Helper method

    View Slide

  34. Setup S3 Bucket
    function  createBucket(S3Client  $s3,  $bucket)  
    {  
     if  (!$s3-­‐>doesBucketExist($bucket))  {  
       $s3-­‐>createBucket(['Bucket'  =>  $bucket]);  
       $s3-­‐>waitUntil('BucketExists',  [  
         'Bucket'  =>  $bucket  
       ]);  
     }  
    }  
     
     
     
       $s3-­‐>createBucket(['Bucket'  =>  $bucket]);  
    Operation
    ( or “Command”)
    Parameters

    View Slide

  35. Setup S3 Bucket
    function  createBucket(S3Client  $s3,  $bucket)  
    {  
     if  (!$s3-­‐>doesBucketExist($bucket))  {  
       $s3-­‐>createBucket(['Bucket'  =>  $bucket]);  
       $s3-­‐>waitUntil('BucketExists',  [  
         'Bucket'  =>  $bucket  
       ]);  
     }  
    }  
     
     
     
     
       $s3-­‐>waitUntil('BucketExists',  [  
         'Bucket'  =>  $bucket  
       ]);  
    Waiter

    View Slide

  36. AWS SDK – Waiters
    •  Poll resources until they’re available
    •  Handle asynchronous operations
    $db-­‐>waitUntil('TableExists',  [  
           'TableName'  =>  $table,  
    ]);  
     

    View Slide

  37. Setup DynamoDB Table
    function  createTable(DynamoDbClient  $db,  $table)  
    {  
       $db-­‐>createTable(['TableName'  =>  $table,  ...]);  
       $db-­‐>waitUntil('TableExists',  [  
           'TableName'  =>  $table  
       ]);  
    }  
     

    View Slide

  38. Setup DynamoDB Table
    'TableName'  =>  $table,  
    'AttributeDefinitions'  =>  [  
       ['AttributeName'=>'app',    'AttributeType'=>'S'],  
       ['AttributeName'=>'time’,  'AttributeType'=>'N’]],  
    'KeySchema'  =>  [  
       ['AttributeName'=>'app',    'KeyType'=>'HASH'],  
       ['AttributeName'=>'time',  'KeyType'=>'RANGE’]],  
    'ProvisionedThroughput'  =>  [  
       'ReadCapacityUnits'    =>  5,  
       'WriteCapacityUnits'  =>  1],  
     
     

    View Slide

  39. Funny Face App
    Level #2
    Wherein we build our app logic

    View Slide

  40. Routes – “/” (GET)
    Route::get('/',  function()  {  
       return  View::make('show',  [  
           'faces'  =>  App::make('funnyfaces')-­‐>latest(),  
           'success'  =>  Session::get('success'),  
       ]);  
    });  

    View Slide

  41. Getting the Funny Faces
    public  function  latest($limit  =  25)  
    {  
       $db  =  $this-­‐>sdk-­‐>get('dynamodb');  
       $items  =  $db-­‐>getIterator('Query',  [  
           'TableName'  =>  $this-­‐>cfg['table'],  
           'ScanIndexForward'  =>  false,  
           'Limit'  =>  $limit,  
           'KeyConditions'  =>  [...]  
       ]);  
       return  new  ItemIterator($items);  
    }  

    View Slide

  42. AWS SDK – Iterators
    •  No handling of markers or tokens
    •  Compatible with SPL iterators
    •  Enumerate entire result sets
    •  Lazy loads results
    $items  =  $db-­‐>getIterator('Query',  […]);  
    foreach  ($items  as  $item)  {  
     echo  $item['key']['S'];  
    }  

    View Slide

  43. Routes – “upload” (GET)
    Route::get('upload',  function()  {  
       return  View::make('upload',  [  
           'success'  =>  Session::get('success'),  
       ]);  
    });  

    View Slide

  44. Routes – “upload” (POST)
    try  {  
       $caption  =  Input::get('caption');  
       $file  =  Input::file('photo');  
       if  (!$caption  ||  !$file)  {  
           throw  new  Exception('File  not  uploaded.');  
       }  
       App::make('funnyfaces')-­‐>add($file,  $caption);  
       return  Redirect::to('show')-­‐>with('success',  1);  
    }  catch  (Exception  $e)  {  
       Log::error($e-­‐>getMessage());  
       return  Redirect::to('upload')-­‐>with('success’,0);  
    }  

    View Slide

  45. Adding a Funny Face (part 1)
    $s3  =  $this-­‐>sdk-­‐>get('s3');  
    $result  =  $s3-­‐>putObject([  
       'Bucket'  =>  $this-­‐>cfg['bucket'],  
       'Key'  =>  $file-­‐>getFileName(),  
       'Body'  =>  fopen($file-­‐>getPathname(),  'r'),  
       'ACL'  =>  'public-­‐read',  
    ]);  
     
    $url  =  $result['ObjectURL'];  

    View Slide

  46. Adding a Funny Face (part 2)
    $db  =  $this-­‐>sdk-­‐>get('dynamodb');  
    $result  =  $db-­‐>putItem([  
       'TableName'  =>  $this-­‐>cfg['table'],  
       'Item'  =>  [  
           'app'  =>  ['S'  =>  $this-­‐>cfg['hashkey']],  
           'time'  =>  ['N'  =>  (string)  time()],  
           'src'  =>  ['S'  =>  $url],  
           'caption'  =>  ['S'  =>  $caption],  
       ],  
    ]);  

    View Slide

  47. Funny Face App
    Level #3
    Wherein we deploy to the cloud

    View Slide

  48. More AWS Services
    AWS Elastic Beanstalk
    An easy way to deploy/manage
    applications in the Cloud.
    AWS IAM
    (Identity and Access Management)
    Enables you to control access
    to your AWS resources

    View Slide

  49. IAM Roles & Instance Profiles

    View Slide

  50. Elastic Beanstalk CLI Tool
    Step  1  –  Sets  up  project  for  EB  
    $  eb  init  
     
    Step  2  –  Creates  EB  environment  
    $  eb  start
     
    Step  3+  –  Deploys  new  versions  
    $  git  aws.push  

    View Slide

  51. EB Console and API
    $eb-­‐>createEnvironment([…]);  
    $eb-­‐>createApplication([…]);  
    $eb-­‐>createApplicationVersion([…]);  
     

    View Slide

  52. .ebextensions
    You may need to do composer self-update
     
    In  .ebextensions/01_update_composer.config:  
    commands:  
       01_update_composer:  
           command:  export  COMPOSER_HOME=/root  &&  
               /usr/bin/composer.phar  self-­‐update  
     
    option_settings:  
       -­‐  namespace:  aws:elasticbeanstalk:application:environment  
           option_name:  COMPOSER_HOME  
           value:  /root  
     

    View Slide

  53. What Have We Made?

    View Slide

  54. Funny Face App
    Step #4
    Wherein we add more cool stuff

    View Slide

  55. Add Amazon Route 53

    View Slide

  56. Add Amazon CloudFront

    View Slide

  57. Add Amazon SQS
    Resize/process photos in the background?
     
    Queue::push('ProcessPhoto',  [  
       'bucket'  =>  Config::get('ff.bucket'),  
       'key'  =>  $file-­‐>getFileName(),  
       'caption'  =>  Input::get('caption'),  
    ]);  

    View Slide

  58. Configuring SQS for Laravel
    In app/config/queue.php:
    'connections'  =>  array(  
       'sqs'  =>  array(  
       'driver'  =>  'sqs',  
       'queue'    =>  'your-­‐queue-­‐url',  
       'region'  =>  'us-­‐east-­‐1',  
     )  
    )  

    View Slide

  59. Adding SQS to Architecture

    View Slide

  60. Funny Face App
    Nice Work! J
    https://github.com/jeremeamia/FunnyFacesL4ExampleApp

    View Slide

  61. aws for
    artisans
    by @jeremeamia
    @awsforphp
    #aws #laracon
    Feedback: https://joind.in/11330

    View Slide

  62. Resources
    •  h"ps://github.com/aws/aws-­‐sdk-­‐php  
    •  h"p://docs.aws.amazon.com/aws-­‐sdk-­‐php/guide/latest/index.html  
    •  h"p://blogs.aws.amazon.com/php  
    •  h"ps://github.com/jeremeamia/FunnyFacesL4ExampleApp  
    •  h"ps://twi"er.com/awsforphp    (@awsforphp)  
    •  h"ps://twi"er.com/aws_eb    (@aws_eb)  
    •  h"p://docs.aws.amazon.com/elasHcbeanstalk/latest/dg/create_deploy_PHP_eb.html  
    •  h"p://docs.aws.amazon.com/elasHcbeanstalk/latest/dg/customize-­‐containers.html  
    •  h"p://www.michaelgallego.fr/blog/2013/08/19/solving-­‐the-­‐elasHc-­‐beanstalk-­‐
    composer-­‐deployment-­‐problems/  

    View Slide