Custom CLI to deploy a dockerized Spring Boot application to AWS Elastic Beanstalk.
This folder contains the sample code for a Spring boot application. See the instructions below for how to deploy and run this application.
- PostgreSQL => Version 9.6 or higher is required. For development environment a docker-compose is provided within this project.
- Java 8
-
Go to the application directory.
-
Deploy BBDD dependencies:
docker-compose up
-
Run the application:
./gradlew run
-
Build the application:
./gradlew build
This command will generated the following jar:
build/libs/helloworld-0.0.1-SNAPSHOT.jar
-
Run the application:
java -jar helloworld-0.0.1-SNAPSHOT.jar --spring.profiles.active=pro
In both cases, application will run in the 8000 port.
Note: In deploy time a script initializing the Database will be executed, this script could take more than 3 minutes.
This application provides a REST API for get users info.
-
URL:
/users/{userId}
-
Method:
GET
-
Response:
{"id":104,"name":"user104","surname":"surname104","type":3}
Gets the users of the given type.
-
URL:
/users?userType={userTypeId}
-
Method:
GET
-
Response:
[ {"id":23,"name":"user23","surname":"surname23","type":6}, {"id":32,"name":"user32","surname":"surname32","type":6}, {"id":38,"name":"user38","surname":"surname38","type":6} ]
Possible values of userType
are between 1
and 10
.
Application and access logs will be generated in the following folder: /var/log/helloworld
The deploy.py
CLI deploys the Spring boot example application to AWS Elastic Beanstalk performing the following tasks:
- Create a boto3 session to store the AWS credentials and the region to use for the deployment. If there is any configuration defined through environment variables or stored in AWS CLI
~/.aws
folder, the AWS credentials and the region are directly retrieved from there (it is possible to specify the profile to use as optional argument). Otherwise, the CLI asks for these parameters interactively. - Check if the Elastic Beanstalk application is already created, and if not, create it.
- Build the Spring boot example application.
- Create the ZIP package (source bundle) for the new application version.
- Upload the application version package to a source bundle S3 bucket.
- Create the new application version for the Elastic Beanstalk application.
- Create the environment if it does not exist or has been previously terminated, or update it if it is already created. The CLI check if there is an operation in progress in the environment and wait for it to be completed before updating or recreating it.
- Python 3.3+
- Boto3
-
The
aws-elasticbeanstalk-ec2-role
instance profile (AWS IAM EC2 Role) created in the AWS account: -
The
aws-elasticbeanstalk-service-role
service role (AWS IAM Elastic Beanstalk Role) created in the AWS account: -
An IAM User or an AWS IAM Role attached to the EC2 instance (only for executions from EC2 instances) with the following IAM Managed Policy attached:
AWSElasticBeanstalkFullAccess
-
Pip tool for Python packages management. Installation:
# From Linux $ curl -O https://bootstrap.pypa.io/get-pip.py $ sudo python3 get-pip.py # From macOS $ brew install python
-
AWS SDK for Python. Installation:
# From Linux $ sudo pip3 install boto3 # From macOS $ pip3 install boto3
Here you have the message that you will get if you request help to the deploy.py
CLI:
$ ./deploy.py --help
usage: deploy.py [-h] -a APPLICATION_NAME -e ENVIRONMENT_NAME [-p PROFILE]
Custom CLI to deploy an application to AWS Elastic Beanstalk
optional arguments:
-h, --help show this help message and exit
Options:
-a APPLICATION_NAME, --application-name APPLICATION_NAME
Name of the Elastic Beanstalk application
-e ENVIRONMENT_NAME, --environment-name ENVIRONMENT_NAME
Name of the environment for the Elastic Beanstalk
application
-p PROFILE, --profile PROFILE
Use a specific profile from AWS CLI stored
configurations
This project provides the following configuration profiles:
env.yaml.staging
=> Configuration profile intended for staging environments deployed for development, test, QA or demo purposes (lower cost and performance). This profile allows to deploy a single-instance type environment (henceforthSingleInstance
) made up of one EC2 instance with an Elastic IP address to serve the application, and a Single-AZ RDS instance to host the databases.env.yaml.production
=> Configuration profile intended for environments with productive loads. This profile allows to deploy a load-balancing, autoscaling type environment (henceforthLoadBalanced
) made up of an Auto Scaling group of EC2 instances with an ELB to serve the application, and a Multi-AZ RDS instance to host the databases.
# Deployment of a staging environment
$ ln -sf env.yaml.staging env.yaml
$ ./deploy.py --application-name helloworld --environment-name test [--profile <aws_cli_profile>]
# Deployment of a productive environment
$ ln -sf env.yaml.production env.yaml
$ ./deploy.py --application-name helloworld --environment-name live [--profile <aws_cli_profile>]
If you need to modify any settings provided in this project or add new ones, feel free to fork or import this repository and apply the changes you need to fulfil your use case.
Here are some common customizations that you might want to add to an environment:
-
To deploy a
SingleInstance
type environment in a existing custom VPC, add the following configuration block to theenv.yaml.staging
file:aws:ec2:vpc: VPCId: <vpc_id> Subnets: <subnet_1a_id>,<subnet_1b_id>,... # Subnet IDs for EC2 instance DBSubnets: <subnet_2a_id>,<subnet_2b_id>,... # Subnet IDs for RDS instance AssociatePublicIpAddress: true # True required for immutable deployments/updates
-
To deploy a
LoadBalanced
type environment in a existing custom VPC, add the following settings to the existingaws:ec2:vpc
namespace inenv.yaml.production
file:aws:ec2:vpc: ELBScheme: public # This setting is already defined VPCId: <vpc_id> ELBSubnets: <subnet_3a_id>,<subnet_3b_id>,... # Subnet IDs for ELB Subnets: <subnet_1a_id>,<subnet_1b_id>,... # Subnet IDs for Auto Scaling group DBSubnets: <subnet_2a_id>,<subnet_2b_id>,... # Subnet IDs for RDS instance AssociatePublicIpAddress: true # Review this option in https://amzn.to/2Vhgt5B
-
To configure HTTPS in a
LoadBalanced
type environment for a custom domain using an ACM issued certificate, add the following configuration block to theenv.yaml.production
file:aws:elb:listener:443: ListenerProtocol: HTTPS InstancePort: '80' InstanceProtocol: HTTP ListenerEnabled: true SSLCertificateId: <acm_certificate_arn>
Then modify the
InstancePort
setting belonging to theaws:elb:listener:80
namespace replacing the port80
by81
. -
To configure a SSH key pair to securely log into the EC2 instance/s belonging to an environment, add the following setting to the existing
aws:autoscaling:launchconfiguration
namespace in any of theenv.yaml.<config_profile>
files:aws:autoscaling:launchconfiguration: . . . . . . EC2KeyName: <key_pair_name>