Save 37% off PRO during our Black Friday Sale! »

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.

Ca57a7cfac69ba3abf517470f3770aae?s=128

Jeremy Lindblom

May 15, 2014
Tweet

Transcript

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

  2. Hi, I’m Jeremy. or @jeremeamia Seattle PHP User Group or

    @seaphp AWS SDK for PHP @awsforphp
  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.
  4. None
  5. None
  6. “The Cloud”

  7. The Clooouuud

  8. The term "Cloud Computing" refers to the on-demand delivery of

    IT resources via the Internet with pay-as-you-go pricing.
  9. IT Resources? Servers • Computing Nodes Distributed Queues • Databases

    Push Notifications File Storage • Load Balancers Content Delivery Networks Cache Clusters • more…
  10. AWS services each have an API, so you can control

    your resources through programs and scripts.
  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  
  12. None
  13. None
  14. With the AWS Service Provider for Laravel:

  15. None
  16. None
  17. None
  18. STORAGE   VOLUMES   KEY  PAIRS   STATIC  IPs  

    FIREWALLS  
  19. Amazon  EC2  

  20. Amazon  EC2   Amazon  S3   Amazon  RDS   Amazon

     SQS   Elas?c   Transcoder  
  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  
  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
  23. Hundreds of Thousands of Customers in 190 Countries

  24. Let’s Build Something!

  25. Funny Face App

  26. Funny Face App

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

  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",      ...   }  
  29. Add the AWS Service Provider In your app/config/app.php:    'providers'

     =>  array(          ...          'Aws\Laravel\AwsServiceProvider',      )            'aliases'  =>  array(          ...          'Aws\Laravel\AwsFacade',      )  
  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    
  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  
  32. Setup S3 Bucket function  createBucket(S3Client  $s3,  $bucket)   {  

     if  (!$s3-­‐>doesBucketExist($bucket))  {      $s3-­‐>createBucket(['Bucket'  =>  $bucket]);      $s3-­‐>waitUntil('BucketExists',  [        'Bucket'  =>  $bucket      ]);    }   }  
  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
  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
  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
  36. AWS SDK – Waiters •  Poll resources until they’re available

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

       $db-­‐>createTable(['TableName'  =>  $table,  ...]);      $db-­‐>waitUntil('TableExists',  [          'TableName'  =>  $table      ]);   }    
  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],      
  39. Funny Face App Level #2 Wherein we build our app

    logic
  40. Routes – “/” (GET) Route::get('/',  function()  {      return

     View::make('show',  [          'faces'  =>  App::make('funnyfaces')-­‐>latest(),          'success'  =>  Session::get('success'),      ]);   });  
  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);   }  
  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'];   }  
  43. Routes – “upload” (GET) Route::get('upload',  function()  {      return

     View::make('upload',  [          'success'  =>  Session::get('success'),      ]);   });  
  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);   }  
  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'];  
  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],      ],   ]);  
  47. Funny Face App Level #3 Wherein we deploy to the

    cloud
  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
  49. IAM Roles & Instance Profiles

  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  
  51. EB Console and API $eb-­‐>createEnvironment([…]);   $eb-­‐>createApplication([…]);   $eb-­‐>createApplicationVersion([…]);  

     
  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    
  53. What Have We Made?

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

    stuff
  55. Add Amazon Route 53

  56. Add Amazon CloudFront

  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'),   ]);  
  58. Configuring SQS for Laravel In app/config/queue.php: 'connections'  =>  array(  

       'sqs'  =>  array(      'driver'  =>  'sqs',      'queue'    =>  'your-­‐queue-­‐url',      'region'  =>  'us-­‐east-­‐1',    )   )  
  59. Adding SQS to Architecture

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

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

  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/