To automate the deployment for a new environment directly from the Bitbucket repository, we need to create a new EC2 instance or use an already existing one.
Setting up a new EC2 instance
Install Docker
To setup a new EC2 instance, first install Docker in the instance (if not installed already):
- Update packages:
sudo apt-get update
- Intall Docker engine:
sudo apt-get install docker-ce docker-ce-cli containerd.io
Then install Docker compose
- Download current release:
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- Apply executable permissions to the binary:
sudo chmod +x /usr/local/bin/docker-compose
Install Code Deploy Agent
Code Deploy Agent will take care of fetching the project from S3 and deploying the code into the target server. To install Code Deploy Agent execute the following commands:
sudo apt-get update sudo apt-get install -y ruby wget cd /home/ubuntu wget https://aws-codedeploy-eu-west-1.s3.eu-west-1.amazonaws.com/latest/install chmod +x ./install sudo ./install auto sudo service codedeploy-agent status
Add the App to Code deploy
- Create the app (if doesn’t exist already) on https://eu-west-1.console.aws.amazon.com/codesuite/codedeploy/applications?region=eu-west-1
- Restart the EC2 Instance (important).
Update Application Deployment groups
We need to Update Application Deployment groups to define which EC2 instances will be the target of the deployment.
- For instance for the app “My project” go to https://eu-west-1.console.aws.amazon.com/codesuite/codedeploy/applications/my_project?region=eu-west-1
- Add a new Deployment group, for instance for the app “My project” testing environment, the name could be
CodeDeployMyProjectTestingGroup
. - Add the Key and Value of the Tag “Name” of the EC2 instance you created earlier (on “Tags” section).
- In “Deployment Type” select “In-place“.
- In “Environment configuration” select “Amazon EC2 instances“.
- In “Deployment settings” select “CodeDeployDefault.AllAtOnce“.
- Disable Load Balancer.
Attach Code Deploy role to the new EC2 instance
Go into AWS EC2 instances section:
- Click on Actions button.
- Click on Instance Settings.
- Click on Security → Modify IAM Role.
- Select CodeDeploy-EC2-Instance-Profile and Apply.
Add deployment files on project’s repository
The deployment requires the following files:
scripts/start_server.sh
: Script that will be executed on the remote EC2 instance, taking care of stopping the currently running server, build the new project and restart the server.scripts/deployment.cfg
: Script with configuration parameters used by thescripts/start_server.sh
script explained earlier.appspec.yml
: The code deploy file defining the steps/scripts that should be executed during the deployment. Also allows to define a preventive timeout to make the deployment fail when is exceeded.bitbucket-pipelines.yml
: Contains a pipeline for each environment in which you want to deploy the project. For instance if we need to add a new Testing environment for the app “My Project”, we would need to add the following code into the custom section:
.. .. custom: My Project (Testing): - step: name: Compress project image: atlassian/default-image:2 script: - sed -i "s/\(MY_DEPLOYMENT_GROUP *= *\).*/\1CodeDeployMyProjectTestingGroup/" scripts/deployment.cfg - zip -r my_project.zip * artifacts: - my_project.zip - step: name: Upload to S3 services: - docker script: - pipe: atlassian/aws-code-deploy:0.5.3 variables: AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION} COMMAND: 'upload' APPLICATION_NAME: ${APPLICATION_NAME} ZIP_FILE: 'my_project.zip' S3_BUCKET: 'my_bucket' FOLDER: $APPLICATION_NAME VERSION_LABEL: 'my_project' - step: name: Deploy to EC2 instance script: - pipe: atlassian/aws-code-deploy:0.5.3 variables: AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION} COMMAND: 'deploy' APPLICATION_NAME: ${APPLICATION_NAME} DEPLOYMENT_GROUP: 'CodeDeployMyProjectTestingGroup' FILE_EXISTS_BEHAVIOR: 'OVERWRITE' BUNDLE_TYPE: 'zip' WAIT: 'true' S3_BUCKET: 'my_bucket' FOLDER: $APPLICATION_NAME VERSION_LABEL: 'my_project' IGNORE_APPLICATION_STOP_FAILURES: 'true'