Commit 25d193f9 authored by Arunodhayam's avatar Arunodhayam
Browse files

Add IaC and ConfigManagement

parent acbf20b0
## ansible-role-lstu
An ansible role deploy the application on host machine(Ubuntu 20.04)
## terraform-aws-lstu
A terraform plan creates necessary AWS infrastructure and deploy the lufi. This terraform plan uses the above ansible roles `ansible-role-lufi` to configure the application on AWS.
\ No newline at end of file
Ansible-Role-Lstu
=========
This role installs the and configures lstu on Debian/Ubuntu servers with nginx web server configuration.
Role Variables
--------------
| Variable name | Value | Description |
| ------------- | ----- | ----------- |
| `app_dir` | /var/www/lstu | Set the application directory for the best practice |
| `lstu_owner` | www-data | Set the application user for the best practice |
| `lstu_group` | www-data | Set the application group for the best practice |
| `_contact` | contact.example.com | contact option (mandatory), where you have to put some way for the users to contact you. |
| `_secret` | IWIWojnokd | secret option (mandatory) array of random strings used to encrypt cookies |
| `_project_version` | master | We can chose the project version either Master branch, Dev branch or tag based |
| `_server_name` | IP address (or) CNAME/FQDN | Mention the Server Name for the Nginx configurations |
Sample example of use in a playbook
--------------
The following code has been tested with Ubuntu 20.04
```yaml
- name: "install lstu"
hosts: enter your hosts file
become: yes
role:
- ansible-role-lstu
vars:
lstu_owner: "www-data"
lstu_group: "www-data"
app_dir: "/var/www/lstu"
_contact: "contact.example.com"
_report: "report@example.com"
_project_version: "master"
_server_name: "IP address (or) CNAME/FQDN"
```
Contributing
------------
Don’t hesitate to create a pull request
---
# handlers file for ansible-role-lstu
- name: restart nginx
service: name=nginx state=restarted
#apprun.yml
---
- name: This command will install the postgress module
ansible.builtin.shell:
cmd: carton install --deployment --without=test --without=sqlite --without=mysql
chdir: "{{ app_dir }}"
- name: Upload application file
template:
src: ../templates/lstu.conf.j2
dest: "{{ app_dir }}/lstu.conf"
- name: Run the command for app_executes
ansible.builtin.shell:
cmd: carton exec hypnotoad script/lstu
chdir: "{{ app_dir }}"
- name: Nginx configuration file add
template:
src: ../templates/app.conf
dest: /etc/nginx/conf.d/
mode: '0644'
notify: restart nginx
\ No newline at end of file
#dependencies.yaml
---
- name: Lstu | Update apt cache
ansible.builtin.apt: update_cache=yes
changed_when: no
- name: Install Dependencies
ansible.builtin.apt:
name:
- nginx
- carton
- build-essential
- libpng-dev
- libssl-dev
- libpq-dev
- zlib1g-dev
- libmojo-sqlite-perl
state: present
\ No newline at end of file
#gitclone
---
- name: Clone the repository
ansible.builtin.git:
repo: 'https://framagit.org/luc/lstu.git'
dest: "{{ app_dir }}"
clone: yes
update: yes
version: "{{ _project_version }}"
- name: Change the owner
ansible.builtin.file:
path: "{{ app_dir }}"
owner: "{{ lstu_owner }}"
group: "{{ lstu_group }}"
state: directory
recurse: yes
---
# tasks file for ansible-role-lstu
- include: dependencies.yaml
- include: gitclone.yaml
- include: apprun.yaml
\ No newline at end of file
upstream lstu {
server 127.0.0.1:8080;
}
server {
listen 80;
listen [::]:80;
server_name {{ _server_name }};
access_log /var/log/nginx/lstu.access.log;
error_log /var/log/nginx/lstu.error.log;
location / {
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Remote-Port $remote_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://lstu;
proxy_redirect http://lstu https://lstu.example.org;
}
}
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
{
####################
# Hypnotoad settings
####################
# see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings
hypnotoad => {
# array of IP addresses and ports you want to listen to
listen => ['http://0.0.0.0:8080'],
# if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1
# if you use Lstu directly, let it commented
#proxy => 1,
},
# put a way to contact you here and uncomment it
# MANDATORY
contact => '{{ _contact }}',
# array of random strings used to encrypt cookies
# optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT
secret => ['{{ _secret }}'],
# secret passphrase to access some admin features
# If you don't want to have a plain text password in configuration,
# use hashed_adminpwd instead
# optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either
#adminpwd => 's3cr3T',
# secret hashed passphrase to access some admin features
# Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal
# optional, but you won't have access to admin /stats if not set and if adminpwd is not set either
#hashed_adminpwd => '94b2feede6ea5e2eec62f457ecb7d3f719b24d19c29d4e5466246a31908fc23b',
# choose a theme. See the available themes in `themes` directory
# optional, default is 'default'
#theme => 'default',
# number of URLs to be displayed per page in /stats
# optional, default is 10
#page_offset => 10,
# length of the random URL
# optional, default is 8
#length => 8,
# how many URLs will be provisioned in a batch ?
# optional, default is 5
#provis_step => 5,
# max number of URLs to be provisioned
# optional, default is 100
#provisioning => 100,
# URL sub-directory in which you want Lstu to be accessible
# example: you want to have Lstu under https://example.org/lstu/
# => set prefix to '/lstu' or to '/lstu/', it doesn't matter
# optional, defaut is /
#prefix => '/',
# array of authorized domains for API calls.
# if you want to authorize everyone to use the API: ['*']
# optional, no domains allowed by default
#allowed_domains => ['http://1.example.com', 'http://2.example.com'],
# if set, the shortened URLs will use this domain
# optional
#fixed_domain => 'example.org',
# choose what database you want to use
# valid choices are sqlite, postgresql and mysql (all lowercase)
# optional, default is sqlite
#dbtype => 'sqlite',
# SQLite ONLY - only used if dbtype is set to sqlite
# define a path to the SQLite database
# you can define it relative to lstu directory or set an absolute path
# remember that it has to be in a directory writable by Lstu user
# optional, default is lstu.db
#db_path => 'lstu.db',
# PostgreSQL ONLY - only used if dbtype is set to postgresql
# these are the credentials to access the PostgreSQL database
# mandatory if you choosed postgresql as dbtype
pgdb => {
database => 'lstu',
host => 'localhost',
# optional, default is 5432
port => 5432,
user => 'DBUSER',
pwd => 'DBPASSWORD',
# optional, default is 1
#max_connections => 1,
},
# MySQL ONLY - only used if dbtype is set to mysql
# these are the credentials to access the MySQL database
# mandatory if you choosed mysql as dbtype
#mysqldb => {
# database => 'lstu',
# host => 'localhost',
# # optional, default is 3306
# #port => 3306,
# user => 'DBUSER',
# pwd => 'DBPASSWORD',
# # optional, default is 5 (set to 0 to disable persistent connections)
# #max_connections => 5,
#},
# Rate-limiting for the API
# After ban_min_strike requests in a second, the IP address will be
# banned for one hour.
# If it continues to query the API during this ban time at least
# ban_min_strike times, it will be banned for a month.
# optional, default is 3
#ban_min_strike => 3,
# Ban whitelist
# You can whitelist IP addresses to prevent you from being banned
# Be careful, the IP addresses are compared as string, not as IP addresses
# a network range will not work
# Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬
# optional, default is an empty array
#ban_whitelist => [],
# Ban blacklist
# You can blacklist IP addresses to always ban those IP addresses
# Be careful, the IP addresses are compared as string, not as IP addresses
# a network range will not work
# Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬
# optional, default is an empty array
#ban_blacklist => [],
# define an URL to the Piwik instance and the ID of a website to track
# set if you want to track views in Piwik
# optional, Piwik tracking is disabled by default
#piwik => {
# url => 'http://piwik.example.com',
# idsite => '1',
#},
# use Minion instead of directly increase counters
# need to launch a minion worker service if enabled
# optional, Minion is disabled by default
# It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,
# postgresql for postgresql, etc.
#minion => {
# enabled => 0,
# # SQLite ONLY - only used if if you choose sqlite as DB type,
# # define the path to the minion database
# # you can define it relative to lstu directory or set an absolute path
# # remember that it has to be in a directory writable by Lutim user
# # optional, default is minion.db
# db_path => 'minion.db',
# # PostgreSQL ONLY - only used if you choose postgresql as DB type
# # these are the credentials to access the Minion's PostgreSQL database
# # mandatory if you choosed postgresql as DB type, no default
# pgdb => {
# database => 'lstu_minion',
# host => 'localhost',
# # optional, default is 5432
# port => 5432,
# user => 'DBUSER',
# pwd => 'DBPASSWORD'
# },
# # MySQL ONLY - only used if you choose mysql as DB type
# # these are the credentials to access the Minion's MySQL database
# # mandatory if you choosed mysql as DB type, no default
# mysqldb => {
# database => 'lstu_minion',
# host => 'localhost',
# # optional, default is 3306
# #port => 3306,
# user => 'DBUSER',
# pwd => 'DBPASSWORD',
# },
#},
# set `ldap` if you want that only authenticated users can shorten URLs
# please note that everybody can still use shortend URLs
# optional, no default
#ldap => {
# uri => 'ldaps://ldap.example.org', # server URI
# user_tree => 'ou=users,dc=example,dc=org', # search base DN
# bind_dn => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN
# bind_pwd => 'secr3t', # search bind password
# user_attr => 'uid', # user attribute (uid, mail, sAMAccountName, etc.)
# user_filter => '(!(uid=ldap_user))', # user filter (to exclude some users, etc.)
#},
# set `htpasswd` if you want to use an htpasswd file instead of ldap
# create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`
# make sure that lstu can read the file!
# optional, no default
#htpasswd => 'lstu.passwd',
# if you've set ldap or htpasswd above, the session will last `session_duration` seconds before
# the user needs to reauthenticate
# optional, default is 3600
#session_duration => 3600,
# how many redirections are allowed for the shortened URL before considering it as a spam?
# optional, default is 2. Set to -1 to allow infinite redirections (not recommended)
#max_redir => 2,
# spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam
# optional, no default
#spam_blacklist_regex => 'foo|bar',
# spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam
# optional, no default
#spam_path_blacklist_regex => 'foo|bar',
# spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam
# optional, no default
#spam_whitelist_regex => 'foo|bar',
# set to 1 to skip SpamHaus check (not recommended)
# optional, default is 0
#skip_spamhaus => 0,
# put your Google API key to enable Google safebrowsing check
# This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.
# Google does not get the URLs that are checked.
# Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started
# TL;DR: https://console.developers.google.com/projectselector/apis/library
# optional, no default
#safebrowsing_api_key => '',
# array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.
# If set to [], the cache is disabled
# optional, default is []
#memcached_servers => [],
# Content-Security-Policy header that will be sent by Lstu
# Set to '' to disable CSP header
# https://content-security-policy.com/ provides a good documentation about CSP.
# https://report-uri.com/home/generate provides a tool to generate a CSP header.
# optional, default is "default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'"
# the default value is good for `default` and `milligram` themes
#csp => "default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'",
# X-Frame-Options header that will be sent by Lstu
# Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'
# Set to '' to disable X-Frame-Options header
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
# Please note that this will add a "frame-ancestors" directive to the CSP header (see above) accordingly
# to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)
# optional, default is 'DENY'
#x_frame_options => 'DENY',
# X-Content-Type-Options that will be sent by Lstu
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
# Set to '' to disable X-Content-Type-Options header
# optional, default is 'nosniff'
#x_content_type_options => 'nosniff',
# X-XSS-Protection that will be sent by Lstu
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
# Set to '' to disable X-XSS-Protection header
# optional, default is '1; mode=block'
#x_xss_protection => '1; mode=block',
# Log creator's IP address
# Set to 1 if you want to register the IP addresses of URL creators
# optional, default is 0
#log_creator_ip => 0,
};
---
# vars file for ansible-role-lstu
lstu_owner: "www-data"
lstu_group: "www-data"
app_dir: "/var/www/lstu"
_contact: ""
_secret: ""
_project_version: ""
_server_name: ""
# Terraform-AWS-Deploy
This terraform plan create the resourcess of EC2 instance
## Terraform Variables
Edit the `vars.tf` file to add the variables as per your need.
| Variable name | Value | Description |
| ------------- | ----- | ----------- |
| `aws_region` | us-east-1 | Set the region |
| `vpc_cidr` | 10.0.0.0/16 | Set the cidr value for the vpc |
| `public_subnet_cidr` | 10.0.2.0/24 | Set the cidr value for the public subnet |
| `user` | ubuntu | Set the EC2 instance user name |
| `public_key` | /home/user_name/.ssh/id_rsa_pub | Set the publickey value for the ec2 instance from the host machine |
| `private_key` | /home/user_name/.ssh/id_rsa | Set the private key value for the ec2 instance from the hostmachine |
| `aws_access_key` | AWSACCESSKEY | Enter your aws access key |
| `aws_secrete_key` | AWSSECRETEKEY | Enter your aws secrete key |
| `instance_name` | lstu_app_instance | Set the name for instance |
#Create the VPC
resource "aws_vpc" "vpc" {
cidr_block = "${var.vpc_cidr}"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "lstu-master-vpc"
}
}
# Create InternetGateWay and attach to VPC
resource "aws_internet_gateway" "IGW" {
vpc_id = "${aws_vpc.vpc.id}"
tags = {
"Name" = "lstu-master-igw"
}
}
# Create a public subnet
resource "aws_subnet" "publicsubnet" {
vpc_id = "${aws_vpc.vpc.id}"
cidr_block = "${var.public_subnet_cidr}"
map_public_ip_on_launch = true
tags = {
Name = "lstu-master-us-east-1-public"
}
}
# Create routeTable
resource "aws_route_table" "publicroute" {
vpc_id = "${aws_vpc.vpc.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.IGW.id}"
}
tags = {
Name = "lstu-master-us-east-1-public-rt"
}
}
resource "aws_main_route_table_association" "mainRTB" {
vpc_id = "${aws_vpc.vpc.id}"
route_table_id = "${aws_route_table.publicroute.id}"
}
## Create security group
resource "aws_security_group" "security" {
name = "lstu-master-sg"
description = "allow all traffic"
vpc_id = "${aws_vpc.vpc.id}"
ingress {
description = "allow all traffic"
from_port = "0"
to_port = "65535"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "allow port SSH"
from_port = "22"
to_port = "22"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Add ubuntu AMI
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
#Create key_pair for the instance
resource "aws_key_pair" "genkey" {
key_name = "lstu.webapp"
public_key = "${file(var.public_key)}"
}
# Craete ec2 instance
resource "aws_instance" "ec2_instance" {
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.medium"
associate_public_ip_address = "true"
subnet_id = "${aws_subnet.publicsubnet.id}"
vpc_security_group_ids = ["${aws_security_group.security.id}"]
key_name = "lstu.webapp"
connection {
agent = false
type = "ssh"
host = aws_instance.ec2_instance.public_dns
private_key = "${file(var.private_key)}"
user = "${var.user}"
}
provisioner "remote-exec" {
inline = [
"sudo apt update -y",
"sudo apt install python3.9 -y",
]
}
provisioner "local-exec" {
command = <<EOT
sleep 120 && \
> hosts && \
echo "[lstu]" | tee -a hosts && \
echo "${aws_instance.ec2_instance.public_ip} ansible_user=${var.user} ansible_ssh_private_key_file=${var.private_key}" | tee -a hosts && \
export ANSIBLE_HOST_KEY_CHECKING=False && \
ansible-playbook -u ${var.user} --private-key ${var.private_key} -i hosts site.yaml
EOT
}
tags = {
Name = "${var.instance_name}"
}
}