Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Elastic Beanstalk using PHP with Private Composer Repositories

How do I utilize private composer repositories when deploying with Amazon AWS Elastic Beanstalk in a PHP environment? Specifically using GitHub (Q & A style, answer following)

like image 695
four43 Avatar asked Feb 20 '14 20:02

four43


People also ask

Does Elastic Beanstalk support PHP?

Elastic Beanstalk provides platforms for programming languages (Go, Java, Node. js, PHP, Python, Ruby), application servers (Tomcat, Passenger, Puma), and Docker containers. Some platforms have multiple concurrently-supported versions.

How do I install composer in Elastic Beanstalk?

Use a Composer file to install dependencies on instances Use a composer. json file in the root of your project source to use composer to install packages that your application requires on your environment's Amazon EC2 instances. When a composer. json file is present, Elastic Beanstalk runs composer.

When should you not use Elastic Beanstalk?

Elastic Beanstalk is a bad choice if you need worker processes. The whole point of a worker process is to perform a task in the background without slowing down your main web app. But Elastic Beanstalk doesn't support this option in a scalable way.


1 Answers

We needed to use a private library for one of our PHP projects we were deploying via AWS's Elastic Beanstalk (EB). This private library is hosted on GitHub, although similar git hosting (your own server, BitBucket, etc.) probably has similar authentication and could use this solution for deployment.

We used SSH credentials to get at the private git repository. Since we are using GitHub, we used GitHub's Deploy Keys (https://help.github.com/articles/managing-deploy-keys#deploy-keys) These keys allow read only access to a specific repository, which is perfect for our needs. Evaluate the best solution for your needs, GitHub has great pros and cons listed for each method.

Our chosen solution embeds the deploy key in with the repository. This is a bit of a security hole. We are dealing with all private repos, with (ideally) secure servers, but this still is a bit of a security risk.

All of this ended up being a bit of a hassle with the way the PHP stack is deployed with Elastic Beanstalk, composer.json was getting auto-run too early and the keys weren't in place beforehand. We found a workaround.

This assumes you already have your deployment setup, but are just stuck at deploying keys. We used the eb cli tools provided by AWS (eb init, eb branch, eb start, etc.) to get things up and going, as well as the git hooks, git aws.push to deploy.

Once we have our Deploy Keys, we can add our library to our composer.json file using the SSH address:

{
...
"require": {
        "repository/project": ">=1.0.0"
},
...
"repositories": [
    {
        "type": "git",
        "url":  "[email protected]:repository/project.git"
    }
]
}

Configure your .gitignore so the composer.lock file is committed and in your repository as well as the vendor folder without it's contents:

[remove composer.lock from file if it exists]
vendor/*

We prefer keeping the composer.lock file in the repository anyway as it locks in the version used in testing. When we move to a production environment we ensure the application is running with the same libraries we tested against. The vendor folder is required to trick EB into not auto-running the composer.phar install process. We need it to wait until we have the ssh keys in place.

Setting up the keys: I couldn't find a good way to affiliate the key and accept github.com as a known_host via scripting. I ended up SSHing to the EB managed server with the software half deployed, added the id_rsa and id_rsa.pub key files to the ~root/.ssh/ (with 400 perms remember!) then trying ssh -T [email protected] (as github recommends) This will prompt to accept the host and add an entry to the ~root/.ssh/known_hosts file. Copy the contents of this file to where you are working on the project.

We are creating all of the setup scripts in the .ebextensions/ folder to configure the Linux server for deployment. This folder is removed (from what I can tell) from the server after pre deployment stage. We are using the PHP 5.5 64bit Amazon AMI solution. Move the id_rsa and id_rsa.pub keys into the the new .ebextensions folder. Also add a file called known_hosts to the folder with the known_hosts contents we provided earlier. Now that we have the 3 files we need, we need to create a final deployment instruction file: 01-github-deploy-keys.config (name the file however you like)

container_commands:
    11-move-priv-key:
        command: "mv ~root/.ssh/id_rsa ~root/.ssh/id_rsa.bak; cp .ebextensions/id_rsa ~root/.ssh/id_rsa; chmod 400 ~root/.ssh/id_rsa;"
    12-move-pub-key:
        command: "mv ~root/.ssh/id_rsa.pub ~root/.ssh/id_rsa.pub.bak; cp .ebextensions/id_rsa.pub ~root/.ssh/id_rsa.pub; chmod 400 ~root/.ssh/id_rsa.pub;"
    12-known-hosts:
        command: "mv ~root/.ssh/known_hosts ~root/.ssh/known_hosts.bak; cp .ebextensions/known_hosts ~root/.ssh/known_hosts; chmod 644 ~root/.ssh/known_hosts;"
    20-install-composer:
        command: "./composer.phar install;"

Remember YAML files uses 4 spaces, not tabs! See the AWS documentation for how these container_commands work: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#customize-containers-format-commands They will run after the files are pulled from the repository. These commands in "container_commands" section have a working directory of your project, so local paths are preferred.

Add all of these files need to be added and committed to the repository. Run your git aws.push to deploy.

In order to test the setup properly you will need to remove the server from the EB solution stack and re-add it. I just go into the EC2 control panel and find the managed server for this project and terminate it. EB will automatically create a new one for you and attach it once it is ready. Double check your logs, specifically the /var/log/cfn-init.log section. It is probably best to turn off SSH access to the servers via security group at this point. I believe EB restricts logins to root over SSH but just to be sure you may want to disable SSH access all together via firewall/security groups. You shouldn't need to ssh into individual boxes for configuration as they should be seen as volatile.

This was written as a Q & A on 2014-02-20, please post any comments or fixes.

Thanks, - Seth

like image 193
four43 Avatar answered Oct 15 '22 14:10

four43