Skip to content

Commit

Permalink
Create a playbook to deploy a simple flask web app into high availabi…
Browse files Browse the repository at this point in the history
…lity architecture
  • Loading branch information
GomathiselviS committed Sep 20, 2023
1 parent 868f1d4 commit 45cc0d3
Show file tree
Hide file tree
Showing 6 changed files with 502 additions and 3 deletions.
129 changes: 129 additions & 0 deletions playbooks/webapp/tasks/create_aurora_db_cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
- name: Create resources playbook
module_defaults:
group/aws:
aws_access_key: "{{ aws_access_key | default(omit) }}"
aws_secret_key: "{{ aws_secret_key | default(omit) }}"
security_token: "{{ security_token | default(omit) }}"
block:
- name: Get security group id
amazon.aws.ec2_security_group_info:
filters:
group-name: "{{ rds_secgroup_name }}"
region: "{{ test_primary_cluster_region }}"
register: rds_primary_sg

- name: Create rds global database
amazon.cloud.rds_global_cluster:
global_cluster_identifier: "{{ test_global_cluster_name }}"
engine: "aurora-postgresql"
engine_version: "15.2"
region: "{{ test_primary_cluster_region }}"
state: present
register: create_global_result

- name: Create a primary cluster for global database
amazon.aws.rds_cluster:
global_cluster_identifier: "{{ test_global_cluster_name }}"
db_cluster_identifier: "{{ test_primary_cluster_name }}"
region: "{{ test_primary_cluster_region }}"
engine: "aurora-postgresql"
engine_version: "15.2"
username: "{{ deploy_flask_app_rds_master_username }}"
password: "{{ deploy_flask_app_rds_master_password }}"
db_subnet_group_name: "{{ rds_subnet_group_name }}"
vpc_security_group_ids:
- "{{ rds_primary_sg.security_groups[0].group_id }}"
register: create_primary_result

- name: Create an instance connected to primary cluster
amazon.aws.rds_instance:
db_cluster_identifier: "{{ test_primary_cluster_name }}"
db_instance_identifier: "{{ test_primary_cluster_name }}-instance"
db_name: "{{ rds_instance_name }}"
region: "{{ test_primary_cluster_region }}"
engine: "aurora-postgresql"
db_instance_class: "{{ test_instance_class }}"
monitoring_interval: 0
skip_final_snapshot: true

- name: Get primary instance info
amazon.aws.rds_instance_info:
db_instance_identifier: "{{ test_primary_cluster_name }}-instance"
region: "{{ test_primary_cluster_region }}"
register: primary_instance_info_result

- name: Get primary cluster info
amazon.aws.rds_cluster_info:
db_cluster_identifier: "{{ test_primary_cluster_name }}"
region: "{{ test_primary_cluster_region }}"
register: primary_cluster_info_result

- name: Get global db info
command: "aws rds describe-global-clusters --global-cluster-identifier {{ test_global_cluster_name }}"
register: global_cluster_info_result

- name: convert it to an object
set_fact:
global_cluster_info: "{{ global_cluster_info_result.stdout | from_json }}"

- name: Assert that primary cluster is a part of global db
assert:
that:
- global_cluster_info.GlobalClusters[0].GlobalClusterMembers[0].DBClusterArn == primary_cluster_info_result.clusters[0].db_cluster_arn

# Create replica cluster -------------------------------------------------------------------------------
- name: Get security group id
amazon.aws.ec2_security_group_info:
filters:
group-name: "{{ rds_secgroup_name }}"
region: "{{ test_replica_cluster_region }}"
register: rds_replica_sg

- name: Create a replica cluster for global database
amazon.aws.rds_cluster:
global_cluster_identifier: "{{ test_global_cluster_name }}"
db_cluster_identifier: "{{ test_replica_cluster_name }}"
engine: "aurora-postgresql"
engine_version: "{{ global_cluster_info.GlobalClusters[0].EngineVersion }}" # replica cluster engine version needs to be exact same as global db engine version
db_subnet_group_name: "{{ rds_subnet_group_name }}"
vpc_security_group_ids:
- "{{ rds_replica_sg.security_groups[0].group_id }}"
region: "{{ test_replica_cluster_region }}"
register: create_replica_result

- name: Create an instance connected to replica cluster
amazon.aws.rds_instance:
db_cluster_identifier: "{{ test_replica_cluster_name }}"
db_instance_identifier: "{{ test_replica_cluster_name }}-instance"
db_name: "{{ rds_instance_name }}"
region: "{{ test_replica_cluster_region }}"
engine: "aurora-postgresql"
db_instance_class: "{{ test_instance_class }}"
monitoring_interval: 0
skip_final_snapshot: true

- name: Get replica instance info
amazon.aws.rds_instance_info:
db_instance_identifier: "{{ test_replica_cluster_name }}-instance"
region: "{{ test_replica_cluster_region }}"
register: replica_instance_info_result

- name: Get replica cluster info
amazon.aws.rds_cluster_info:
db_cluster_identifier: "{{ test_replica_cluster_name }}"
region: "{{ test_replica_cluster_region }}"
register: replica_cluster_info_result

- name: Get global db info
command: "aws rds describe-global-clusters --global-cluster-identifier {{ test_global_cluster_name }}"
register: global_cluster_info_result

- name: convert it to an object
set_fact:
global_cluster_info: "{{ global_cluster_info_result.stdout | from_json }}"

- name: Assert that replica cluster is a part of global db
assert:
that:
- global_cluster_info.GlobalClusters[0].GlobalClusterMembers[1].DBClusterArn == replica_cluster_info_result.clusters[0].db_cluster_arn
181 changes: 181 additions & 0 deletions playbooks/webapp/tasks/create_aurora_setup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
---
- name: Set 'region' variable
ansible.builtin.set_fact:
region: "{{ region | default(aws_region) }}"

- name: Create resources playbook
module_defaults:
group/aws:
aws_access_key: "{{ aws_access_key | default(omit) }}"
aws_secret_key: "{{ aws_secret_key | default(omit) }}"
security_token: "{{ security_token | default(omit) }}"
region: "{{ region }}"
block:
- name: Get image ID to create an instance
amazon.aws.ec2_ami_info:
filters:
architecture: x86_64
virtualization-type: hvm
root-device-type: ebs
name: "{{ image_filter }}"
register: images

- name: List availability zones from aws region
amazon.aws.aws_az_info:
register: zones

- name: Set region_av_zones' variable
ansible.builtin.set_fact:
region_av_zones: "{{ zones.availability_zones | map(attribute='zone_name') }}"

- name: Create a VPC to work in
amazon.aws.ec2_vpc_net:
cidr_block: "{{ vpc_cidr }}"
name: "{{ vpc_name }}"
register: vpc

# Public and Private subnets should be in the same availability zone
# So that the load balancer can target workers instances
- name: Set 'shared_az' variable
ansible.builtin.set_fact:
shared_az: "{{ region_av_zones[0] }}"

- name: Create a public subnet for bastion
amazon.aws.ec2_vpc_subnet:
vpc_id: "{{ vpc.vpc.id }}"
cidr: "{{ subnet_cidr[0] }}"
az: "{{ shared_az }}"
register: subnet

- name: Create private subnet for workers
amazon.aws.ec2_vpc_subnet:
vpc_id: "{{ vpc.vpc.id }}"
cidr: "{{ subnet_cidr[1] }}"
az: "{{ shared_az }}"
register: private_subnet

- name: Create another private subnet for RDS
amazon.aws.ec2_vpc_subnet:
vpc_id: "{{ vpc.vpc.id }}"
cidr: "{{ subnet_cidr[2] }}"
az: "{{ region_av_zones[1] }}"
register: rds_subnet

- name: Create subnet group for RDS instance
amazon.aws.rds_subnet_group:
name: "{{ rds_subnet_group_name }}"
description: subnet group for RDS instance to be hidden
subnets:
- "{{ rds_subnet.subnet.id }}"
- "{{ private_subnet.subnet.id }}"
state: present

- name: Create internet gateway attached to the VPC
amazon.aws.ec2_vpc_igw:
vpc_id: "{{ vpc.vpc.id }}"
state: present
register: internet_gw

- name: Create NAT gateway (allow access to internet for instances in private subnet)
amazon.aws.ec2_vpc_nat_gateway:
subnet_id: "{{ subnet.subnet.id }}"
if_exist_do_not_create: true
wait: true
state: present
register: nat_gw

- name: Create Route table for internet gateway (public subnet)
amazon.aws.ec2_vpc_route_table:
vpc_id: "{{ vpc.vpc.id }}"
subnets:
- "{{ subnet.subnet.id }}"
routes:
- dest: 0.0.0.0/0
gateway_id: "{{ internet_gw.gateway_id }}"
lookup: tag
resource_tags:
subnet: public
route: internet
state: present

- name: Create Route table for NAT gateway (private subnet)
amazon.aws.ec2_vpc_route_table:
vpc_id: "{{ vpc.vpc.id }}"
subnets:
- "{{ private_subnet.subnet.id }}"
routes:
- dest: 0.0.0.0/0
gateway_id: "{{ nat_gw.nat_gateway_id }}"
lookup: tag
resource_tags:
subnet: private
route: nat-gateway
state: present

- name: Create security group for bastion
amazon.aws.ec2_security_group:
name: "{{ public_secgroup_name }}"
vpc_id: "{{ vpc.vpc.id }}"
description: Security group for Bastion host
rules:
- cidr_ip: 0.0.0.0/0
proto: tcp
from_port: 22
to_port: 22
- cidr_ip: 0.0.0.0/0
proto: tcp
from_port: "{{ deploy_flask_app_listening_port }}"
to_port: "{{ deploy_flask_app_listening_port }}"
rules_egress:
- cidr_ip: 0.0.0.0/0
proto: -1
tags: "{{ resource_tags }}"
state: present
register: secgroup

- name: Create security group for RDS instance
amazon.aws.ec2_security_group:
name: "{{ rds_secgroup_name }}"
vpc_id: "{{ vpc.vpc.id }}"
description: Security group to allow RDS instance port
rules:
- cidr_ip: 0.0.0.0/0
proto: tcp
from_port: "{{ rds_listening_port }}"
to_port: "{{ rds_listening_port }}"
tags: "{{ resource_tags }}"
state: present
register: rds_sg

- name: Set 'sshkey_file' variable
ansible.builtin.set_fact:
sshkey_file: ~/private-key-{{ deploy_flask_app_sshkey_pair_name }}-{{ region | default(aws_region) }}

- name: Create key pair to connect to the VM
amazon.aws.ec2_key:
name: "{{ deploy_flask_app_sshkey_pair_name }}"
register: rsa_key

- name: Save private key into file
ansible.builtin.copy:
content: "{{ rsa_key.key.private_key }}"
dest: "{{ sshkey_file }}"
mode: 0400
when: rsa_key is changed

- name: Create a virtual machine
amazon.aws.ec2_instance:
name: "{{ deploy_flask_app_bastion_host_name }}"
instance_type: "{{ bastion_host_type }}"
image_id: "{{ images.images.0.image_id }}"
key_name: "{{ deploy_flask_app_sshkey_pair_name }}"
subnet_id: "{{ subnet.subnet.id }}"
network:
assign_public_ip: true
groups:
- "{{ secgroup.group_id }}"
security_groups:
- "{{ secgroup.group_id }}"
wait: true
state: started
register: vm_result
59 changes: 59 additions & 0 deletions playbooks/webapp/tasks/delete_aurora_db_cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
- name: Create resources playbook
module_defaults:
group/aws:
aws_access_key: "{{ aws_access_key | default(omit) }}"
aws_secret_key: "{{ aws_secret_key | default(omit) }}"
security_token: "{{ security_token | default(omit) }}"
block:
- name: Delete instance connected to replica cluster
amazon.aws.rds_instance:
db_cluster_identifier: "{{ test_replica_cluster_name }}"
db_instance_identifier: "{{ test_replica_cluster_name }}-instance"
engine: "aurora-postgresql"
db_instance_class: "{{ test_instance_class }}"
skip_final_snapshot: true
region: "{{ test_replica_cluster_region }}"
state: absent

- name: Delete replica cluster
amazon.aws.rds_cluster:
db_cluster_identifier: "{{ test_replica_cluster_name }}"
global_cluster_identifier: "{{ test_global_cluster_name }}"
engine: "aurora-postgresql"
engine_version: "15.2"
skip_final_snapshot: true
remove_from_global_db: true
region: "{{ test_replica_cluster_region }}"
state: absent

- name: Delete instance connected to primary cluster
amazon.aws.rds_instance:
db_cluster_identifier: "{{ test_primary_cluster_name }}"
db_instance_identifier: "{{ test_primary_cluster_name }}-instance"
engine: "aurora-postgresql"
db_instance_class: "{{ test_instance_class }}"
skip_final_snapshot: true
region: "{{ test_primary_cluster_region }}"
state: absent

- name: Delete primary cluster
amazon.aws.rds_cluster:
db_cluster_identifier: "{{ test_primary_cluster_name }}"
global_cluster_identifier: "{{ test_global_cluster_name }}"
engine: "aurora-postgresql"
engine_version: "15.2"
username: "{{ deploy_flask_app_rds_master_username }}"
password: "{{ deploy_flask_app_rds_master_password }}"
skip_final_snapshot: true
region: "{{ test_replica_cluster_region }}"
state: absent

- name: Delete global db
amazon.cloud.rds_global_cluster:
global_cluster_identifier: "{{ test_global_cluster_name }}"
engine: "aurora-postgresql"
engine_version: "15.2"
region: "{{ test_primary_cluster_region }}"
state: absent

Loading

0 comments on commit 45cc0d3

Please sign in to comment.