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.

Ca57a7cfac69ba3abf517470f3770aae?s=128

Jeremy Lindblom

July 16, 2013
Tweet

Transcript

  1. Controlling the! AWS Cloud! with PHP!

  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  
  3. Amazon Web Services o"ers a complete set of infrastructure and

    application services that enable you to run virtually everything in the cloud.!
  4. In other words…! AWS is a bunch of building blocks.!

  5. Some of these blocks are for! building your infrastructure,! Amazon

    Elastic Compute Cloud! (EC2)! Amazon Relational Database Service! (RDS)! Amazon! Route 53!
  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)!
  7. And some of these blocks build on each! other to

    create complete solutions.! AWS CloudFormation! AWS! Elastic Beanstalk! AWS! OpsWorks!
  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#!
  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!
  10. AWS services each have an API,! so you can control

    your resources! through programs and scripts.!
  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!
  12. <?php     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.';    
  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!
  14. Amazon EC2 Vocabulary! •  Amazon Machine!   Image (AMI)! • 

    Instance! •  Instance Type! •  Region! •  Availability Zone! •  Security Group! •  Key Pair!
  15. Instance Type Families! •  Micro! •  Standard! •  High CPU!

    •  High Memory! •  High I/O! •  High Storage! •  High Memory Cluster! •  Cluster Compute! •  Cluster GPU!
  16. Regions and Availability Zones (AZ)! us-east-1, eu-west-1, ap-southeast-2, etc.!

  17. Amazon EC2 Vocabulary! •  Amazon Machine!   Image (AMI)! • 

    Instance! •  Instance Type! •  Region! •  Availability Zone! •  Security Group! •  Key Pair!
  18. <?php     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',   ));  
  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');  
  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')),          )      )   ));  
  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,   ));  
  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'   ));  
  23. Poof! A working PHP 5.5 web server! running in the

    AWS cloud!!
  24. None
  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!
  26. Amazon EC2 and its friends form the! foundation of scalable

    apps and solutions! Elastic Load Balancing! Need EC2 Auto Scaling! Amazon! CloudWatch!
  27. AWS CloudFormation! AWS! OpsWorks! AWS! Elastic Beanstalk! Highest Flexibility! Easiest

    Con$guration!
  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?!
  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!
  30. •  DevOps solution for apps! •  Organized w/ stacks &

    layers! •  Deploy from a GitHub repo! •  Customize with Chef recipes! •  Nice management console! AWS OpsWorks!
  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!
  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!
  33. CloudFormation Templates! •  AWSTemplateFormatVersion! •  Description! •  Parameters! •  Mappings!

    •  Resources! •  Outputs!
  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]!
  35. <?php     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'          )      )   ));  
  36. Hand-selected Features! of the AWS SDK for PHP!

  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";   }  
  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);
  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);
  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!
  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!
  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!
  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!
  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!
  45. @jeremeamia! http://webjeremy.com! Thanks!! http://github.com/aws/aws-sdk-php AWS SDK for PHP Star the

    on
  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/!