Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Controlling the AWS Cloud with PHP

Controlling the AWS Cloud with PHP

Amazon Web Services offers a complete set of infrastructure and application services that enable you to run virtually everything in the cloud. These services each have an API, and that allows you to control your resources through your programs and scripts. I’ll introduce you to some of the infrastructure and deployment services like Amazon EC2, AWS CloudFormation, AWS Elastic Beanstalk, and AWS OpsWorks, and show how you can provision servers, and even entire application stacks, with PHP using the AWS SDK for PHP.

Jeremy Lindblom

July 16, 2013
Tweet

More Decks by Jeremy Lindblom

Other Decks in Technology

Transcript

  1. Controlling the!
    AWS Cloud!
    with PHP!

    View Slide

  2. $  whoami  
    >  Jeremy  Lindblom  <@jeremeamia>  
    >  PHP  Software  Engineer  at  AWS  
    >  Works  on  the  AWS  SDK  for  PHP  
    >  Seattle  PHP  Meetup  Group  organizer  
    >  http://webjeremy.com  

    View Slide

  3. Amazon Web Services o"ers a
    complete set of infrastructure and
    application services that enable you to
    run virtually everything in the cloud.!

    View Slide

  4. In other words…!
    AWS is a bunch of building blocks.!

    View Slide

  5. Some of these blocks are for!
    building your infrastructure,!
    Amazon Elastic
    Compute Cloud!
    (EC2)!
    Amazon Relational
    Database Service!
    (RDS)!
    Amazon!
    Route 53!

    View Slide

  6. Some of these blocks are for!
    building your application,!
    Amazon Simple
    Storage Service!
    (S3)!
    Amazon Simple
    Queue Service!
    (SQS)!
    Amazon Simple
    Email Service!
    (SES)!

    View Slide

  7. And some of these blocks build on each!
    other to create complete solutions.!
    AWS
    CloudFormation!
    AWS!
    Elastic Beanstalk!
    AWS!
    OpsWorks!

    View Slide

  8. Amazon Route53!
    Amazon S3!
    Amazon SES!
    Amazon SimpleDB!
    Amazon SNS!
    Amazon SQS!
    Amazon SWF!
    Amazon VPC!
    Auto Scaling!
    AWS Data Pipeline!
    AWS Elastic Beanstalk!
    AWS Import/Export!
    AWS OpsWorks!
    AWS Storage Gateway!
    AWS Support!
    Elastic Load Balancing!
    Amazon CloudFormation!
    Amazon CloudFront!
    Amazon CloudSearch!
    Amazon CloudWatch!
    Amazon Direct Connect!
    Amazon DynamoDB!
    Amazon EBS!
    Amazon EC2!
    Amazon ElastiCache!
    Amazon Elastic Transcoder!
    Amazon EMR!
    Amazon Glacier!
    Amazon IAM!
    Amazon Mechanical Turk!
    Amazon RDS!
    Amazon Redshi#!

    View Slide

  9. Amazon Route53!
    Amazon S3!
    Amazon SES!
    Amazon SimpleDB!
    Amazon SNS!
    Amazon SQS!
    Amazon SWF!
    Amazon VPC!
    Auto Scaling!
    AWS Data Pipeline!
    AWS Elastic Beanstalk!
    AWS Import/Export!
    AWS OpsWorks!
    AWS Storage Gateway!
    AWS Support!
    Elastic Load Balancing!
    Amazon CloudFormation!
    Amazon CloudFront!
    Amazon CloudSearch!
    Amazon CloudWatch!
    Amazon Direct Connect!
    Amazon DynamoDB!
    Amazon EBS!
    Amazon EC2!
    Amazon ElastiCache!
    Amazon Elastic Transcoder!
    Amazon EMR!
    Amazon Glacier!
    Amazon IAM!
    Amazon Mechanical Turk!
    Amazon RDS!
    Amazon Redshi#!
    8 services!
    less than!
    a year old!

    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 some servers!
    from PHP by using the AWS SDK for PHP!
    to talk to the Amazon EC2 API!
    Amazon EC2!

    View Slide

  12.  
    require  'vendor/autoload.php';  
    use  Aws\Ec2\Ec2Client;  
     
    $ec2Client  =  Ec2Client::factory('config.php');  
    $result  =  $ec2Client-­‐>runInstances(array(  
       'ImageId'            =>  'ami-­‐af45d59f',  
       'MinCount'          =>  1,  
       'MaxCount'          =>  3,  
       'InstanceType'  =>  'm1.small',  
    ));  
     
    $ids  =  $result-­‐>getPath('Instances/*/InstanceId');  
    $ec2Client-­‐>waitUntilInstanceRunning(array(  
       'InstanceIds'  =>  $ids,  
    ));  
    echo  'Provisioned  '  .  count($ids)  .  '  servers.';  
     

    View Slide

  13. AWS SDK for PHP!
    •  PHP 5.3+, PSR compliant, Composer install!
    •  Built on top of Guzzle (guzzlephp.org)!
    •  Persistent connections, parallel requests!
    •  Simple array-like inputs and outputs!
    •  Easy pagination, "waiters", other helpers!
    •  Event hooks, plugins, wire logging!
    •  https://github.com/aws/aws-sdk-php!

    View Slide

  14. Amazon EC2 Vocabulary!
    •  Amazon Machine!
      Image (AMI)!
    •  Instance!
    •  Instance Type!
    •  Region!
    •  Availability Zone!
    •  Security Group!
    •  Key Pair!

    View Slide

  15. Instance Type Families!
    •  Micro!
    •  Standard!
    •  High CPU!
    •  High Memory!
    •  High I/O!
    •  High Storage!
    •  High Memory Cluster!
    •  Cluster Compute!
    •  Cluster GPU!

    View Slide

  16. Regions and Availability Zones (AZ)!
    us-east-1, eu-west-1, ap-southeast-2, etc.!

    View Slide

  17. Amazon EC2 Vocabulary!
    •  Amazon Machine!
      Image (AMI)!
    •  Instance!
    •  Instance Type!
    •  Region!
    •  Availability Zone!
    •  Security Group!
    •  Key Pair!

    View Slide

  18.  
    require  'vendor/autoload.php';  
     
    use  Aws\Ec2\Ec2Client;  
     
    //  Create  an  EC2  client  for  the  us-­‐east-­‐1  region  
    $ec2Client  =  Ec2Client::factory(array(  
       'key'        =>  'your-­‐access-­‐key-­‐id',  
       'secret'  =>  'your-­‐secret-­‐key',  
       'region'  =>  'us-­‐east-­‐1',  
    ));  

    View Slide

  19. //  Pick  some  clever  names  for  our  resources  
    $kpName  =  'my-­‐keypair';  
    $sgName  =  'my-­‐security-­‐group';  
     
    //  Create  the  key  pair  and  save  the  private  key  
    $result  =  $ec2Client-­‐>createKeyPair(array(  
       'KeyName'  =>  $kpName  
    ));  
    $kpFile  =  getenv('HOME')."/.ssh/{$kpName}.pem";  
    file_put_contents($kpFile,  $result['keyMaterial']);  
    chmod($kpFile,  0400);  
     
    //  Create  the  security  group  
    $result  =  $ec2Client-­‐>createSecurityGroup(array(  
       'GroupName'      =>  $sgName,  
       'Description'  =>  'basic  web  server'  
    ));  
    $sgId  =  $result-­‐>get  ('GroupId');  

    View Slide

  20. //  Set  ingress  rules  for  the  security  group  
    $ec2Client-­‐>authorizeSecurityGroupIngress(array(  
       'GroupName'          =>  $sgName,  
       'IpPermissions'  =>  array(  
           array('IpProtocol'  =>  'tcp',  
                       'FromPort'      =>  80,  
                       'ToPort'          =>  80,  
                       'IpRanges'      =>  array(  
                             array('CidrIp'  =>  '0.0.0.0/0')),  
           ),  
           array('IpProtocol'  =>  'tcp',  
                       'FromPort'      =>  22,  
                       'ToPort'          =>  22,  
                       'IpRanges'      =>  array(  
                           array('CidrIp'  =>  '0.0.0.0/0')),  
           )  
       )  
    ));  

    View Slide

  21. //  Launch  an  instance  and  specify  a  KP,  SG,  and  AZ
    $result  =  $ec2Client-­‐>runInstances(array(  
       'ImageId'                =>  'ami-­‐af45d59f',  
       'MinCount'              =>  1,  
       'MaxCount'              =>  1,  
       'InstanceType'      =>  'm1.small',  
       'KeyName'                =>  $keyName,  
       'SecurityGroups'  =>  array($secGroupName),  
       'Placement'            =>  array(  
           'AvailabilityZone'  =>  'us-­‐east-­‐1d',  
       )  
    ));  
    $ids  =  $result-­‐>getPath('Instances/*/InstanceId');  
     
    //  Wait  until  the  instance  is  launched  
    $ec2Client-­‐>waitUntilInstanceRunning(array(  
       'InstanceIds'  =>  $ids,  
    ));  

    View Slide

  22. //  Describe  the  now-­‐running  instance  
    $result  =  $ec2Client-­‐>describeInstances(array(  
       'InstanceIds'  =>  $ids,  
    ));  
     
    //  Extract  the  DNS  name  from  the  results  
    print_r($result-­‐>getPath(  
       'Reservations/*/Instances/*/PublicDnsName'  
    ));  

    View Slide

  23. Poof! A working PHP 5.5 web server!
    running in the AWS cloud!!

    View Slide

  24. View Slide

  25. Reserved!
    !
    Make a low, one-
    time payment and
    receive a discount
    on the hourly charge!
    !
    For committed
    utilization!
    Free Tier!
    !
    Get Started on AWS
    with free usage & no
    commitment!
    !
    For proof-of-
    concepts and
    getting started!
    On-Demand !
    !
    Pay for compute
    capacity by the hour
    with no long-term
    commitments!
    !
    For spiky workloads, !
    or to de$ne needs!
    Spot!
    !
    Bid for unused
    capacity. Price
    %uctuates based on
    supply and demand!
    !
    For time-insensitive or
    transient workloads!
    EC2 Purchasing Options!

    View Slide

  26. Amazon EC2 and its friends form the!
    foundation of scalable apps and solutions!
    Elastic Load
    Balancing!
    Need
    EC2
    Auto Scaling! Amazon!
    CloudWatch!

    View Slide

  27. AWS
    CloudFormation!
    AWS!
    OpsWorks!
    AWS!
    Elastic Beanstalk!
    Highest Flexibility! Easiest Con$guration!

    View Slide

  28. AWS
    CloudFormation!
    AWS!
    OpsWorks!
    AWS!
    Elastic Beanstalk!
    How do you pick which one to use?!
    1.  Does it align with your use case?!
    2.  Which one do you like the best?!

    View Slide

  29. •  Create and manage entire!
    stacks of AWS resources!
    AWS CloudFormation!
    •  Stack is de$ned by a JSON template!
    •  Can manage templates w/ version control!
    •  Premade example templates available!
    •  Foundation of Elastic Beanstalk!

    View Slide

  30. •  DevOps solution for apps!
    •  Organized w/ stacks & layers!
    •  Deploy from a GitHub repo!
    •  Customize with Chef recipes!
    •  Nice management console!
    AWS OpsWorks!

    View Slide

  31. •  Easy to get started!
    •  PHP 5.3 or PHP 5.4!
    •  Does load balancing and auto scaling!
    •  Deploy via Git, upload (console), or S3 (API)!
    •  Installs Composer dependencies for you!
    •  Customize via API/console, ebextensions
    con$g, and custom hook scripts!
    AWS Elastic Beanstalk!

    View Slide

  32. AWS
    CloudFormation!
    AWS!
    OpsWorks!
    AWS!
    Elastic Beanstalk!
    What do they have in common?!
    1.  No additional charge for these services!
    2.  You still have full access to your AWS
    resources managed by these services!

    View Slide

  33. CloudFormation Templates!
    •  AWSTemplateFormatVersion!
    •  Description!
    •  Parameters!
    •  Mappings!
    •  Resources!
    •  Outputs!

    View Slide

  34. Let's take a look at a CloudFormation!
    template that builds a PHP stack!
    with multiple servers!
    !
    https://s3.amazonaws.com/code-samples-jcl/cfn-php-tpl.json!
    [DEMO]!

    View Slide

  35.  
    require  'vendor/autoload.php';  
    use  Aws\CloudFormation\CloudFormationClient;  
     
    $cfn    =  CloudFormationClient::factory('cfg.php');  
    $tpl    =  'https://s3.amazonaws.com/code-­‐samples-­‐jcl'  
    $tpl  .=  '/cfn-­‐php-­‐tpl.json';  
    $result  =  $cfn-­‐>createStack(array(  
       'StackName'      =>  'TestPhpStack',  
       'TemplateURL'  =>  $tpl,  
       'Parameters'    =>  array(  
           array(  
               'ParameterKey'      =>  'KeyName',  
               'ParameterValue'  =>  'my-­‐keypair'  
           )  
       )  
    ));  

    View Slide

  36. Hand-selected Features!
    of the AWS SDK for PHP!

    View Slide

  37. Iterators!
    •  Iterate through entire result sets!
    •  No handling of markers or tokens!
    •  Uses SPL iterators!
    $list  =  $s3-­‐>getListObjectsIterator([  
       'Bucket'  =>  'my-­‐bucket'  
    ]);  
    foreach  ($list  as  $object)  {  
       echo  $object['Key']  .  "\n";  
    }  

    View Slide

  38. SDK 1.x – Before Iterators!
    $dynamo_db  =  new  AmazonDynamoDB();  
    $start_key  =  null;  
    $people  =  array();  
       
    do  {  
       $params  =  array(  
           'TableName'  =>  'people',  
       );  
       
       if  ($start_key)  {
           $params['ExclusiveStartKey']  =  array(
               'HashKeyElement'  =>  array(
                   'S'  =>  $start_key
               )
           );
           $start_key  =  null;
       }
     
       $response  =  $dynamo_db-­‐>scan($params);
       if  ($response-­‐>isOK())  {
           foreach  
    ($response-­‐>body-­‐>Items  as  $item)  {
               echo  (string)  $item-­‐>name-­‐>S;
           }
             
           if  ($response-­‐>body-­‐>LastEvaluatedKey)  {
               $start_key  =  (string)  $response-­‐>body  
    -­‐>LastEvaluatedKey-­‐>HashKeyElement-­‐>S;
           }  
       }  else  {
             
           throw  new  DynamoDB_Exception('…');
       }
    }  while  ($start_key);

    View Slide

  39. SDK 1.x – Before Iterators!
    $dynamo_db  =  new  AmazonDynamoDB();  
    $start_key  =  null;  
    $people  =  array();  
       
    do  {  
       $params  =  array(  
           'TableName'  =>  'people',  
       );  
       
       if  ($start_key)  {
           $params['ExclusiveStartKey']  =  array(
               'HashKeyElement'  =>  array(
                   'S'  =>  $start_key
               )
           );
           $start_key  =  null;
       }
     
       $response  =  $dynamo_db-­‐>scan($params);
       if  ($response-­‐>isOK())  {
           foreach  
    ($response-­‐>body-­‐>Items  as  $item)  {
               echo  (string)  $item-­‐>name-­‐>S;
           }
             
           if  ($response-­‐>body-­‐>LastEvaluatedKey)  {
               $start_key  =  (string)  $response-­‐>body  
    -­‐>LastEvaluatedKey-­‐>HashKeyElement-­‐>S;
           }  
       }  else  {
             
           throw  new  DynamoDB_Exception('…');
       }
    }  while  ($start_key);

    View Slide

  40. $db  =  $aws-­‐>get('DynamoDb');  
     
    $scan  =  $db-­‐>getScanIterator(array(  
       'TableName'              =>  'People',  
       'AttributesToGet'  =>  array('Id',  'Name')  
    ));  
     
    foreach  ($scan  as  $person)  {  
       echo  $item['Name']['S'];  
    }    
    Example: Scan Iterator!

    View Slide

  41. $s3-­‐>registerStreamWrapper();  
     
    $path  =  's3://jcl-­‐files/logs/04.log';  
    if  ($file  =  fopen($path,  'r'))  {  
       while  (!feof($file))  {  
           echo  fgets($file);  
       }  
       fclose($file)  
    }  
    S3 Stream Wrapper!

    View Slide

  42. $s3-­‐>registerStreamWrapper();  
     
    $finder  =  new  Finder();  
    $finder-­‐>files()  
       -­‐>in('s3://jcl-­‐files/family-­‐videos')  
       -­‐>size('<  50M')  
       -­‐>date('since  1  year  ago');  
     
    foreach  ($finder  as  $file)  {  
       echo  $file-­‐>getFilename()  .  "\n";  
    }  
    Stream Wrapper + Symfony Finder!

    View Slide

  43. $s3-­‐>uploadDirectory(  
       '/Users/Jeremy/Photos/201307',  //  directory  
       'my-­‐stuff-­‐bucket',                          //  bucket  
       'photos/201307/',                            //  key  prefix  
       array(                                                  //  options  
           'concurrency'  =>  20,  
           'debug'              =>  true,  
           'params'            =>  array(  
               'ACL'  =>  'public-­‐read'  
           )  
       )  
    );  
    S3 Upload Directory!

    View Slide

  44. AWS SDKs and Tools!
    PHP • Java • Python • .NET!
    Ruby • Node.js • iOS • Android!
    SDKs!
    AWS CLI • Visual Studio Plugin!
    Eclipse Plugin • PowerShell Tools!
    Management Console • iOS App!
    !
    Tools!

    View Slide

  45. @jeremeamia!
    http://webjeremy.com!
    Thanks!!
    http://github.com/aws/aws-sdk-php
    AWS SDK for PHP
    Star the
    on

    View Slide

  46. Links!
    •  https://github.com/aws/aws-sdk-php!
    •  http://docs.aws.amazon.com/aws-sdk-php-2/
    guide/latest/index.html!
    •  http://blogs.aws.amazon.com/php!
    •  https://forums.aws.amazon.com/forum.jspa?
    forumID=80!
    •  http://aws.amazon.com/documentation/!
    •  http://aws.amazon.com/cloudformation/aws-
    cloudformation-templates/!

    View Slide