Here are the steps and supporting files needed to deploy Laravel applications from Bitbucket to an autoscaled production environment at AWS. Deployment is handled through Bitbucket Pipelines, from where it moves to AWS CodeDeploy, which places new revisions to instances in an Auto Scaling Group.
This is mostly sample content so tweak to your app's needs. The EC2 instances in this setup use Amazon Linux AMI and will have Apache, PHP and the modules Laravel requires out-of-the-box. The app is deployed to /var/www/app
and the usual optimization commands are run during each deployment.
- S3 bucket
- Stores the deployment package
- Stores resources for setting up instances
- IAM user for Bitbucket
- Allows uploading the deployment package to S3
- Allows interacting with CodeDeploy
- IAM service role for EC2 instances
- Allows reading the S3 bucket
- IAM service role for CodeDeploy
- Allows managing the CodeDeploy app
- EC2 Application Load Balancer + Target Group
- EC2 Launch Configuration + Auto Scaling Group
- CodeDeploy Application
These steps assume you either know your way around these parts or are open to reading the instructions AWS gives you at each step.
- Your app
- Include the files
bitbucket-pipelines.yml
,bitbucket-pipelines-codedeploy.sh
,bitbucket-pipelines-common.sh
,appspec.yml
,codedeploy-prepare.sh
andcodedeploy-setup-app.sh
from this repository to your app's root directory.
- Include the files
- S3
- Create a bucket. This tutorial will use the name
bitbucket-pipelines-bucket
. - Upload an Apache configuration file. See example configuration (production.apache.conf) below.
- Upload a dotenv file for Laravel. See example (production.env) below.
- Create a bucket. This tutorial will use the name
- IAM
- Create a Policy using Create Your Own Policy. This tutorial will use the name
bitbucket-pipelines-deploy-with-codedeploy
. Use the JSON below. - Create a Policy using Create Your Own Policy. This tutorial will use the name
bitbucket-pipelines-manage-app-zip
. Use the JSON below. - Create a Policy using Create Your Own Policy. This tutorial will use the name
bitbucket-pipelines-read-bucket
. Use the JSON below. - Create a User for Programmatic access. This tutorial will use the name
bitbucket-pipelines-user
. Attach thebitbucket-pipelines-deploy-with-codedeploy
andbitbucket-pipelines-manage-app-zip
policies. Keep the generated keys for use in a later step. - Create a Role for EC2 (Service Role). This tutorial will use the name
bitbucket-pipelines-ec2-role
. Attach thebitbucket-pipelines-read-bucket
policy. - Create a Role for CodeDeploy (Service Role). This tutorial will use the name
bitbucket-pipelines-codedeploy-role
. Attach the builtinAWSCodeDeployRole
policy.
- Create a Policy using Create Your Own Policy. This tutorial will use the name
- EC2
- Create an Application Load Balancer. This tutorial will use the name
bitbucket-pipelines-alb
for the ALB andbitbucket-pipelines-tg
for the Target Group. Set a Health Check Path of/health-check.php
. No need to register targets yet. - Create a Launch Configuration. This tutorial will use the name
bitbucket-pipelines-lc
. Use the User data below and select the previosly created EC2 role. - Create an Auto Scaling Group. This tutorial will use the name
bitbucket-pipelines-asg
. Set it to receive traffic from the previously created ALB.
- Create an Application Load Balancer. This tutorial will use the name
- CodeDeploy
- Create an Application. This tutorial will use the name
bitbucket-pipelines-codedeploy-app
for both the app and its group. Selectbitbucket-pipelines-asg
under Auto Scaling Groups. Check to Enable load balancing, then selectbitbucket-pipelines-tg
under Application Load Balancer. Use thebitbucket-pipelines-codedeploy-role
role.
- Create an Application. This tutorial will use the name
- Bitbucket
- Enable Pipelines at your repository's Settings.
- Add the following to Environment variables:
- AWS_ACCESS_KEY_ID: use the access key from earlier
- AWS_SECRET_ACCESS_KEY: use the secret key from earlier and remember to check Secured
- AWS_REGION: use the region you've set all this up in
- AWS_CODEDEPLOY_APP:
bitbucket-pipelines-codedeploy-app
- AWS_CODEDEPLOY_GROUP:
bitbucket-pipelines-codedeploy-app
- AWS_S3_BUCKET:
bitbucket-pipelines-bucket
- Push to master
<Directory /var/www/app>
AllowOverride All
Options FollowSymLinks
</Directory>
<VirtualHost *:80>
DocumentRoot /var/www/html
</VirtualHost>
<VirtualHost *:80>
ServerName app.dev
DocumentRoot /var/www/app/public
</VirtualHost>
APP_ENV=production
APP_DEBUG=false
APP_KEY=your-generated-key-goes-here
APP_URL=http://localhost
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codedeploy:RegisterApplicationRevision",
"codedeploy:CreateDeployment",
"codedeploy:GetDeploymentConfig",
"codedeploy:GetApplicationRevision"
],
"Resource": [
"*"
]
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::bitbucket-pipelines-bucket/packages/*"
]
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::bitbucket-pipelines-bucket/*"
]
}
]
}
#!/bin/bash
yum update -y
yum install -y ruby wget httpd24 php70 php70-mbstring php70-pdo
wget https://aws-codedeploy-eu-west-1.s3.amazonaws.com/latest/install
chmod +x install
./install auto
aws s3 cp s3://bitbucket-pipelines-bucket/production.apache.conf /etc/httpd/conf.d/app.conf
touch /var/www/html/health-check.php
chkconfig httpd on
service httpd start