How to Configure A Service In A Private Server Using Bash script & Creating A Load Balancer In AWS

Nwokolo Emmanuel
16 min readJan 4, 2023

Goals:

  • Creating a vpc with private and public subnets
  • Creating private instances in the private subnet of the vpc
  • Creating a bastion host.
  • Installation and Configuration of Nginx Server on Private Instances Using BASH script
  • Creation of target groups
  • Creating an application load balancer.

BASH scripting is one of the easiest tools to use to configure a server. but you can’t use only bash to configure the server.

because the bash script cannot copy and run itself to a remote server at least not that I have heard of.

that’s why we will be using ansible to copy and run the bash script to these servers.

in this blog, I am going to show you. how to configure a service using BASH script in a private server & how to create a load balancer in AWS.

note that the service you wish to use is your choice. either apache2, wildfly, or Nginx. but in the blog, we are going to be using Nginx!

now you might be wondering “OMG😱 what’s a VPC??”. A VPC is just an isolated private cloud within a public cloud.

we are going to go to our AWS console to create a VPC with its private and public subnets. oops! what’s a subnet?

A subnet, or subnetwork, is a segmented piece of a larger network. More specifically, subnets are a logical partition of an IP network into multiple, smaller network segments.

The Internet Protocol (IP) is the method for sending data from one computer to another over the internet.

1. How To Create A VPC With Private and Public Subnets

Now we are in our console. if you don’t have an account with AWS you can create one here and get some services for free.

in the search box above type in VPC and click on VPC to go to your VPC dashboard. for me, I just recently used it that’s why it was on my recently visited.

By default, the dashboard will look something like this. you can click on any side to enter your VPC space.

We are now in. by default again there should be a VPC service available here so you don’t need to worry. all you need to do is click on the create VPC above.

Now that we are creating our VPC. you will see two options. VPC only and VPC and more. Click on VPC and more.

then your page should look like this. you might be wondering why we used VPC and more.

well, let’s just say it’s to make the creation of the Subnets, NAT gateway, route tables, and other needed services easier.

but just using VPC only creates a VPC for you and you will need to create the other services yourself.

and I love the easier way. let’s just say I am lazy 😂

scrolling down. leave all this as default only if you have a particular specification you have to meet.

but for this blog, we are good to go!

Above you Choose the number of Availability Zones (AZ’s) in which to create your NAT GateWay. now before you click the create VPC.

check if the diagram on the right-hand side is the same as the one below.

With one VPC. 4 subnets (2 private and 2 public), 3 route tables, and 3 network connections. then you can click on the create button.

Then you should see this beautiful page of everything being created for us. now you see the benefits of the VPC and more options.

When it is done. you go back to your VPC dashboard and you see that our VPC has been created.

you can also check your subnets to see your 4 subnets created.

2. Creating our EC2 instance (server)

in this part of the blog, we would need to create an instance and link it to our VPC. well you can do this for so many reasons.

but we are doing it to only allow our load balancer to communicate to the private instances we will create. so, let’s jump right in!

Still on this same search bar. we type in ec2. then options come out. Click on the one you see in the image.

This is the Ec2 dashboard where you can check a lot of things running within that dashboard like the running instances. now we click on instances on the left-hand side.

after clicking on instances. you should see a page that says you should launch an instance. after doing that you will appear on this page above.

the red circled area is where you type in your instance name. you can choose to create multiple instances.

if you look at where the arrow is pointing you should see that it’s one we are creating for this session. you will create the other one.

Scrolling down we see where to pick our specific OS distribution. in this case we are going to be using Ubuntu.

and in the version, we will just leave it in the free tier. but if you have a specific version you want to use then you can change that.

but note your free tier might not cover it. which means you will be billed.

Here, you select the instance type. but you can leave it as default.

you can click on the select key pair above to select a key pair that you have created before or if you haven’t created before you can click on create.

When creating it should look like this. put in the name of your key pair above. make sure you thick the RSA and .pem buttons.

then you can create. note that after creating. a file will be downloaded into your system. make sure you keep that file safe.

it’s what we would use to SSH into our private servers.

Now that we are on the network settings. this is where things get interesting. in the vpc segment.

Click on the new vpc we just created on the subnet segment. Click on one of the private subnets we created.

after that by default the IP address will be disabled. leave it like that.

in the security groups below clear the previous name that was there and name it something you can remember.

NOTE: when you are creating the second server you will need to use the second private subnet for the second server and you don’t need to create a new security group you can just click on “select existing security group”.

You can also add a description for your security group. leave the default security group. then you click on the launch instance.

NOTE: there will have to be two servers that the load balancer will have to connect to. you need to create the second one.

you can follow the previous guide and instructions. doing this helps you learn faster. see you in the next block!

3. Creating a Bastion Host

A bastion host is a server whose purpose is to provide access to a private network from an external network.

This is necessary because our subnets are private, hence, the bastion host which is within the same VPC serves as a bridge to establish a connection to the private subnets.

The best practice is that anyone who needs access to any of the computers inside the VPC must SSH into the bastion host first before doing another SSH to the instance they want to go to.

We would need to create a new instance for the bastion host.

You will create everything exactly the same way but when it comes to the network settings. there would be a slight difference.

select the vpc we have been using. select the public subnet this time not the private.

and enable the public IP address. also, you will need to select your already created key pair.

with an existing security group, you created for the first and second servers. then you can click on the launch instance.

We open the bastion host instance details and click on connect to connect to the bastion host.

Then right there on the SSH client tab. we copy the command that is shown as an example and paste it on our terminal.

Now, before you paste it to log in. you need to check if the .pem file you downloaded is in the same directory you want to log in to.

if the file is not there you can use the command below to create a new file.

nano root-server.pem

after creating it. then you can open the downloaded file and copy the whole contents in it and paste it inside this file you created on your local machine

NOTE: the name of the file should match the name of the file you created and downloaded.

With the command I copied from AWS, I am now inside my bastion host. from here we can now login into our private servers.

but like the example, I gave above the .pem file will need to be created inside this server.

Now that I have input the key inside this file I need to change the modification with this command

chmod 400 root-server1.pem

after doing that. I will need to SSH into my private server. note that the IP address at the end is the private IP address of the server.

ssh -i "key pair name" ubuntu@ip address

4. Installation and Configuration of Nginx Server on Private EC2 Instances Using BASH script

we are going to be using a bash script to configure our Nginx server. this should not be hard. let’s jump right in!

Now I am going to create a new file in my bastion host where my .pem file is. and we will name this file config.sh.

and when you have created this file don’t forget to add the shebang above. so that Linux can detect what kind of script you are writing

#!/bin/bash

now, this should be all we need to configure our Nginx server using the bash script.

but there is a problem.

#!/bin/bash

# command to update and upgrade our servers
sudo apt update && sudo apt dist-upgrade

# command to install nginx
sudo apt install nginx

# command to switch to root user
sudo su

# the command to overide the nginx html page

echo "<h1>This is my server $(hostname -f)</h1>" > /var/www/html/index.nginx-debian.html

# command to exit root user
exit

#the command to enable nginx and restart nginx

sudo systemctl enable nginx && sudo systemctl restart nginx

how do we now put it in the private servers?

we don’t want to SSH into all the servers to put a script and run it. I am too lazy to do that.

I don’t know about you. what do you think? we shouldn’t do that right? right!

so now we will need a little Ansible to copy the scripts to the servers and run them for us.

sounds great? let’s gooo!!

with this script, we can copy our BASH script to the servers and run them using Ansible.

but before we can run our ansible.

firstly, we need to update & upgrade the bastion host server with the commands below:

sudo apt update; sudo apt dist-upgrade -y

second, we would install ansible on the bastion host using the command below.

sudo apt install ansible -y

thirdly, we will need to create three files on our servers. the first is the ansible config file. and it should look like this.

nano ansible.cfg
[defaults]
inventory = inventory
private_key_file = ~/root-server1.pem

Notice the name of the file is ansible.cfg and the defaults are in brackets.

now the private_key_file can be changed that’s if you know the location your key pair is stored.

but in this blog, we store it in the home directory just like other files. Press ctrl O to save the file and ctrl X to exit.

Inventory file

the second file we will need to create is our inventory file where we store the IP address of our other two private instances as you can see above.

nano inventory

note that the name of the file must be inventory.

and now for the final file. we will need to create is a YAML (Yet Another Markup Language) file where we will be storing our ansible playbook as you can see below.

then we input all this into the ansible file we created above:

---

- hosts: all
become: yes
tasks:

- name: update & upgrade server
apt:
update_cache: yes
upgrade: yes

- name: install nginx
apt:
name: nginx
state: latest

- name: copy bash script to server
copy:
src: config.sh
dest: /var/www/html
owner: root
group: root
mode: 0744

- name: Run shell script.
tags: script
shell: sh /var/www/html/config.sh

you will notice there is a change to the playbook.

I just figured out that you can’t copy our script to the path:

/var/www/html

because it does not exist.

so change of plans. we need to update the server and install Nginx using ansible.

we will also need to make a change to our bash script:

#!/bin/bash


# the command to overide the nginx html page

sudo echo "<h1>This is my server $(hostname -f)</h1>" > /var/www/html/index.nginx-debian.html


#the command to enable nginx and restart nginx

sudo systemctl enable nginx && sudo systemctl restart nginx

and now when you are finally done. you need to type in “ls” to make sure all the files in yours are complete like mine.

if not, the playbook will not run.

need to have these four files before the ansible-playbook will be able to work. now let’s test it out!!

the command we will need to run our playbook.

ansible-playbook -i inventory FileName.yml

and as you can see above the scripts and ansible-playbook worked!

I just logged into one of the private servers to check and you see the file was changed!!

5. Creating your Target Groups

Going back to AWS. we will need to create a target group to connect our load balancer and our IP addresses together.

on your EC2 dashboard. Scroll down until you see target groups.

click on it and click on create target groups.

Click on instances. and type in your target group name

Select the vpc we created in this blog. leave everything as default.

then at the bottom of this page click on next.

Now, select the two private IP addresses.

Click on include as pending below. then create a target group.

Currently, there is no load balancer configured for this target group.

Click on the None associated and select the new load balancer.

6. Creating An Application Load Balancer

In this part of the blog, we are going to be creating an application load balancer to communicate with our private servers

Type in the name of the application load balancer. make sure it is on internet facing.

scrolling down. select the vpc we created and click those two boxes and input your first public IP address and the second public address.

in the security group section, we are going to click on create a new security group.

Here you input your security group name. description and on the vpc side you select the vpc we have been using throughout this blog.

When creating your inbound rule create it this way.

there should be two ports 80 and two ports 443.

then on the first port 80. we will be selecting anywhere IPv4.

on the second port 80, we should be selecting anywhere IPv6.

we do the same for port 443 when you are done. you create the security group.

leave the outbound rule as it is. just click on Create

now we go back to our load balancer and update the security groups we just created.

if you check and it’s not there just reload it with the reload button at the side. after adding our security groups.

we move down to target groups and select the target group we created previously in this blog.

Leave everything as a default. and create the load balancer.

7. Configure Instance Security Group to Face Load Balancer

now going back to our EC2 dashboard. just above our target groups, we will see security groups.

Click on it.

navigate to the security group you used for your private instance.

Click on edit inbound rule.

edit the inbound rules by adding a new rule.

and on the port type in port 80.

then in the custom space select the security group you used for your load balancer. and click create.

you are good to go!

now go back to your target groups. as you can see the two servers are both healthy or by any means if they are not.

you can reload the Nginx server in the two private servers by adding this task to your ansible file:

- name: restart nginx
tags: restart
service:
name: nginx
state: restarted
enabled: yes
ansible-playbook -i inventory FileName.yml --tags restartsudo systemctl restart ngnx

now we head back to our load balancer and copy the DNS name. put it on the browser.

yessss!!! it works!

Don’t mind the mistake that it still shows server 2. look at the IP address itself!!

Resources

Here are some other easier ways to do this if you don’t want to use BASH Script:

NOTE: if you have any questions or want to add to this blog. you can message me through E-mail.

I reply faster to people that are subscribed to my newsletter!!

Conclusion

If you loved this blog post give it a like, comment, and don’t forget to click on the follow button.

And if you would love to get an update on the two interesting blogs I will be posting this week then you should sign up for my newsletter!!

--

--

Nwokolo Emmanuel

I am a Cloud Engineer, I love sharing easy solutions to problems that I found difficult. Interested in Open Source | twitter: twitter.com/CloudTopG