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 full-size 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 full-size 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 full-size slide

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

    View full-size 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 full-size 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 full-size slide

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

    View full-size 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 full-size 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 full-size slide

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

    View full-size 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 full-size 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 full-size 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

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

    View full-size slide

  24. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  27. 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 full-size slide

  28. •  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 full-size slide

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

    View full-size slide

  30. •  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 full-size slide

  31. 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 full-size slide

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

    View full-size slide

  33. 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 full-size slide

  34.  
    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 full-size slide

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

    View full-size slide

  36. 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 full-size slide

  37. 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 full-size 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 full-size slide

  39. $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 full-size slide

  40. $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 full-size slide

  41. $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 full-size slide

  42. $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 full-size slide

  43. 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 full-size slide

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

    View full-size slide

  45. 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 full-size slide