This studio will expand on what was learned in the AWS basics unit. Your goal is to deploy the Airwaze app using load-balanced, cloud-based, and modern Dev Ops practices.
application.properties
.ddl-auto
value to update
, we do NOT want Spring Data to run the import.sql
filespring.datasource.url=jdbc:postgresql://${APP_DB_HOST}:${APP_DB_PORT}/${APP_DB_NAME}
spring.datasource.username=${APP_DB_USER}
spring.datasource.password=${APP_DB_PASS}
spring.jpa.hibernate.ddl-auto=update
build/libs
In order to isolate your application instances from other instances in AWS and the open internet, you need to create a Virtal Private Cloud (VPC). This gives you your own little private network in the cloud which can help when establishing access controls as well as keeping your instances private from the rest of AWS. Typically, you’ll have a few of these in an enterprise environment to keep strict boundaries between unrelated services.
A VPC is a way to coordinate and configure how multiple servers will work together and how those servers can be accessed.
Screen shot with red arrow pointing to VPC in the Services list
Screen shot with red circle around the Start VPC Wizard button (image is out of date)
Screen shot with red circle around the VPC with a Single Public Subnet tab
Screen shot of the VPC with a Single Public Subnet configuration window
x.x.x.x/16
block will include 65,536 possible addresses*x.x.x.x/24
, which includes 256 addressesVPC ID
of your VPCScreen shot of the VPC Dashboard with a red circle around the VPC ID
Screen shot of the Virtual Private Cloud sidebar with a red arrow pointing to Subnets
Screen shot with a red circle around the Create Subnet button
10.0.1.0/24
x.x.x.x/24
subnet, that will contain 256 addresses, so increase the third number by one from the previously created subnet.10.0.2.0/24
Screen shot of the Create Subnet configuration window
Now that the VPC is set up and ready for use, you need to create your database server. In the last studio, you installed a PostgreSQL server on your instance. This time, you’ll use AWS’s Relational Database Service (RDS) to host and manage our DB instance.
Screen shot with red arrow pointing to Relational Database Serivce in the Services list
Before creating any instances, you need to create a DB Subnet Group so AWS knows where to place your instance.
Screen shot of the RDS sidebar with a red arrow pointing to Subnet groups
Screen shot of the Subnet group details configuration window
Screen shot of the Add subnets configuration window
Now that you’ve created the database subnets, you need to create a database instance for your application to use.
Screen shot of the Engine options window
Screen shot of the Use case window
db.t2.micro
instance class. This is the smallest, slowest, and least-expensive instance option for RDS.Screen shot of the instance class configuration window for RDS
Next, you’ll set up the instance’s identifier and master user account. Do not set up the application user as the master user. That would introduce a security risk for your database and data if your application were to be compromised. You will set up a separate DB user account later.
DB instance identifier
field.Screen shot of the RDS instance Settings configuration window
Here you’ll indicate where RDS should place your instance and how to secure it.
Screen shot of the RDS instance Network & Security configuration window
Screen shot of the RDS instance Database options configuration window
You’ll also see the security group inbound and outbound rules set up. If the inbound rule doesn’t match your VPC’s subnet CIDR, change that by clicking the gear icon to the right of Security group rules
.
Screen shot of the RDS Dashboard Connect sub-window with a red circle around the instance endpoint
Screen shot of the PostgreSQL inbound rules with a red circle around the VPC’s subnet CIDR
Now that you have created your database, you need to create an instance to connect to it as our template. If you need review on creating an EC2 instance, please see the previous lesson and studio.
You’ll follow the same steps as before, with a few changes that are described here.
Screen shot of the Configure Instnace Details screen
airwaze
system usersystemd
service fileroot
, so sudo
is not needed for these commands. That also means you must be careful when crafting a script to run here.APP_DB_HOST
value to be your RDS instance’s endpoint.Screen shot of the Advanced Details section of the Configure Instance Details screen
#!/bin/bash
# Install Java
apt-get update -y && apt-get install -y openjdk-8-jdk
# Create airwaze user
useradd -M airwaze
mkdir /opt/airwaze
mkdir /etc/opt/airwaze
chown -R airwaze:airwaze /opt/airwaze /etc/opt/airwaze
chmod 777 /opt/airwaze
# Write Airwaze config file
cat << EOF > /etc/opt/airwaze/airwaze.config
APP_DB_HOST=CHANGE TO YOUR RDS ENDPOINT URL (example: rds-instance.us-east-2.rds.amazonaws.com)
APP_DB_PORT=5432
APP_DB_NAME=airwaze_db
APP_DB_USER=airwaze_user
APP_DB_PASS=verysecurepassword
EOF
# Write systemd unit file
cat << EOF > /etc/systemd/system/airwaze.service
[Unit]
Description=Airwaze Studio
After=syslog.target
[Service]
User=airwaze
EnvironmentFile=/etc/opt/airwaze/airwaze.config
ExecStart=/usr/bin/java -jar /opt/airwaze/app.jar SuccessExitStatus=143
Restart=no
[Install]
WantedBy=multi-user.target
EOF
systemctl enable airwaze.service
(on local computer)
$ scp -i ~/.ssh/aws-ssh-key.pem app-0.0.1-SNAPSHOT.jar [email protected]:/opt/airwaze/app.jar
$ scp -i ~/.ssh/aws-ssh-key.pem *.csv [email protected]:/home/ubuntu/
(remote server)
ubuntu$ chmod 555 /opt/airwaze/app.jar
Now that you have your instance set up and ready, you need to log into the server to prepare your database and start the service. During development of the Airwaze studio application, it was set to reload the database on every start of the service. This is not something you want happening in your cloud environment. Instead, you’ll create everything your application needs in your instance by hand.
postgresql
client package on your EC2 instance(on remote server)
ubuntu$ sudo apt-get update
ubuntu$ sudo apt-get install postgresql
(on remote server)
ubuntu$ psql -h rds-instance.us-east-2.rds.amazonaws.com -p 5432 -U rds_master_user airwaze_db
CREATE USER airwaze_user WITH PASSWORD 'verysecurepassword';
CREATE EXTENSION postgis;
CREATE EXTENSION postgis_topology;
CREATE EXTENSION fuzzystrmatch;
CREATE EXTENSION postgis_tiger_geocoder;
CREATE TABLE airport
(
id serial primary key,
airport_id integer,
airport_lat_long geometry,
altitude integer,
city character varying(255),
country character varying(255),
faa_code character varying(255),
icao character varying(255),
name character varying(255),
time_zone character varying(255)
);
CREATE TABLE route
(
id serial primary key,
airline character varying(255),
airline_id integer,
dst character varying(255),
dst_id integer,
route_geom geometry,
src character varying(255),
src_id integer
);
ALTER TABLE airport OWNER to airwaze_user;
ALTER TABLE route OWNER to airwaze_user;
Now that the tables are created, you need to fill them with data.
(on remote server)
ubuntu$ psql -h rds-instance.us-east-2.rds.amazonaws.com -d airwaze_db -U airwaze_user -c "\copy route(src, src_id, dst, dst_id, airline, route_geom) from STDIN DELIMITER ',' CSV HEADER" < /home/ubuntu/routes.csv
ubuntu$ psql -h rds-instance.us-east-2.rds.amazonaws.com -d airwaze_db -U airwaze_user -c "\copy airport(airport_id, name, city, country, faa_code, icao, altitude, time_zone, airport_lat_long) from STDIN DELIMITER ',' CSV HEADER" < /home/ubuntu/Airports.csv
At this point, everything is ready to go on this instance. You no longer need (or want) to connect to the database directly so uninstall the postgresql
client package. Then you may start the Airwaze service.
(on remote server)
ubuntu$ sudo apt-get remove postgresql
ubuntu$ sudo systemctl start airwaze.service
You can run journalctl
as you learned in the previous studio to check the logs for your running service.
(keeps the log open and shows you any new entries, that's what the -f does)
ubuntu$ journalctl -f -u airwaze
(opens the entire log, starting at the top. you can go forward and back with ctrl f and ctrl b)
(note to see the latest issue with your service you will need to go to the END of the log file)
ubuntu$ journalctl -u airwaze
Now that your instance and service are running, return to the EC2 Security Group dashboard. Here you need to enable web access and remove SSH access. This will make your application usable to the world and decrease the risk of unintended access.
Screen shot of the inbound rules for the instance security group
You may now try to access your application at http://ec2-instance.us-east-2.compute.amazonaws.com:8080 in your browser.
The benefit of the cloud is more than just having an application running on a single server in the cloud. You can make your application more resilient by having it run on multiple servers with a load balancer transferring traffic to the least-used server.
To facilitate spinning up more instances, you can take an image of your current instance to start others.
Screen shot of the EC2 Instances dashboard with the Actions menu open
Screen shot of the Create Image configuration window
AWS will then shut down your instance, take an image of it, then restart it. Click the link in the confirmation dialog to montior the process of the image creation.
Screen shot of the Create Image success dialog with a red line below the pending image ami
Once the image creation is complete, you can launch new instances with this image.
Screen shot of the AMIs dashboard with a red circle around Launch
This will start the familiar instance creation process, but with your image rather than the standard Ubuntu image you’ve been using. As before, on Configure Instance Details, select your VPC, public subnet, and assign a Public IP. This time, do not provide a User data script since this image already has the full configuration run.
After creating the instance, return to the EC2 Instances dashboard. Select your new instance and you’ll see it was created from the image you created rather than the Ubuntu AMI used to create the previous one.
Screen shot of the EC2 Instances dashboard with a red line under the AMI ID of the new instance
In order to connect a load balancer (LB), you need to have two public subnets in different availability zones. Return to the VPC Subnet dashboard.
Screen shot of the Create Subnet window
This new subnet is originally created as a private subnet, so you’ll have to change its route table to allow connections with the internet.
Screen shot of the Route Table tab on the new subnet
igw
. This is your VPC’s internet gateway.
* An Internet Gateway allows communication between instances in your VPC and the internet.Screen shot showing a route table that includes an internet gateway
With the new public subnet in place, you can now create your LB.
Screen shot of the EC2 Dashboard with a red arrow pointing to Load Balancers
Screen shot of the Select load balancer type selection screen
HTTP
and port to 80
Screen shot of the Configure Load Balancer window
Screen shot of the Load Balancer Availability Zones window
The Configure Security Settings screen will likely encourage you to improve the LB’s security. This is because you opted to only allow HTTP connections. This is sufficient for the studio, but you should enable HTTPS for every service that can support it in an enterprise environment. Click Next: Configure Security Groups.
You will be presented with a screen similar to one you used when creating your instances. This will allow you to configure the firewall to manage access to your LB.
HTTP
and verify port 80 is selectedScreen shot of the Load Balancer Configure Security Groups window
The next screen allows you to define a target group for the routing behavior of the LB. This will determine what protocol and internal port it uses to communicate with your application servers.
8080
since that is the port Airwaze set up for listeninginstance
target typeScreen shot of the Load Balancer Target group configuration window
Now, you need to register your application instances to your LB so it can route traffic correctly.
Screen shot of the Load Balancer Target Instances configuration window
At this point, AWS will begin configuring the LB. Find and note the DNS name they have assigned your LB.
Screen shot of the Load Balancer Dashboard with a red circle around the new LB’s DNS name
While the LB is starting up, you can configure your application instances to stop listening to the public internet and only to internal traffic.
Screen shot of the inbound rules for the application instances
Now it’s time to see the result of your hard work:
Open http://demo-lb-instance.us-east-2.elb.amazonaws.com in the browser and see the application running.
The real power in a load balancer is it can route traffic away from unhealthy instances. Time to test that out.
Congratulations! You have successfully created a load-balanced application in the cloud.
There’s no bonus mission today. Use your time to work on your project or brush up on topics that you want to learn more about.