{"id":15811,"date":"2023-02-14T06:39:09","date_gmt":"2023-02-14T06:39:09","guid":{"rendered":"https:\/\/www.insentragroup.com\/us\/insights\/uncategorized\/aws-rds-disaster-recovery-for-aap\/"},"modified":"2024-12-13T02:01:23","modified_gmt":"2024-12-13T02:01:23","slug":"aws-rds-disaster-recovery-for-aap","status":"publish","type":"post","link":"https:\/\/www.insentragroup.com\/us\/insights\/geek-speak\/modern-workplace\/aws-rds-disaster-recovery-for-aap\/","title":{"rendered":"AWS RDS Disaster Recovery for AAP: A Guide to Data Protection and High Availability"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>This blog describes the method to recover the Ansible Automation Platform (AAP) database hosted on an AWS RDS PostgresDB in case of data corruption. This method can be also used to clone the database and use it in the development environment (daily snapshots).&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step-By-Step Process<\/h2>\n\n\n\n<p>There are several ways to provide the <a href=\"https:\/\/www.insentragroup.com\/us\/insights\/geek-speak\/modern-workplace\/ansible-disaster-recovery-guide-aws\/\" target=\"_blank\" rel=\"noreferrer noopener\">Disaster Recovery for the Ansible Automation Platform installed in AWS<\/a>. AAP provides a built-in backup method that can be executed by using the same installation script with \u2018-b\u2019 switch: setup.sh -b. This approach backs up the entire AAP configuration, including the Postgres DB, all the controller, execution, and hub nodes. As the result, we have a backup that can be used to recover the entire environment.\u00a0<\/p>\n\n\n\n<p>This approach may prove challenging to implement in a cloud environment as it necessitates a prolonged interruption of the entire AAP environment, and it is best to perform recovery in a newly provisioned environment.&nbsp;<\/p>\n\n\n\n<p>This guide provides a detailed explanation of the steps needed to restore the Ansible Automation Platform&#8217;s DB in AWS when using RDS, without the need for an AAP backup file.<\/p>\n\n\n\n<p>Prerequisites:<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\">\n<li>AAP installed with AWS RDS Database&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>RDS DB is being protected with AWS Snapshots&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>RDS DB snapshot is available&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li>Access to relevant sections of AWS console&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"5\">\n<li>Root access to controller and hub nodes<\/li>\n<\/ol>\n\n\n\n<p>How to restore DB for AAP:&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\">\n<li>Log into AWS&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li>Navigate to RDS &gt; Snapshots&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>Select the Snapshot to restore:<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1006\" height=\"316\" src=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-4.png\" alt=\"\" class=\"wp-image-15812\" srcset=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-4.png 1006w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-4-300x94.png 300w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-4-768x241.png 768w\" sizes=\"(max-width: 1006px) 100vw, 1006px\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li>Select Actions &#8211;&gt; Restore Snapshot:<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"512\" height=\"316\" src=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-5.png\" alt=\"\" class=\"wp-image-15814\" srcset=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-5.png 512w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-5-300x185.png 300w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"5\">\n<li>In the configuration of Restore snapshot, specify a new DB instance identifier, for example &#8212;&gt; aapdb02&nbsp;<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"822\" height=\"652\" src=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-6.png\" alt=\"\" class=\"wp-image-15816\" srcset=\"https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-6.png 822w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-6-300x238.png 300w, https:\/\/www.insentragroup.com\/us\/wp-content\/uploads\/sites\/21\/2023\/02\/image-6-768x609.png 768w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" start=\"6\">\n<li>Ensure all other settings are the same as for the original instance, especially VPC security groups&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"7\">\n<li>Click Restore DB Instance and wait patiently until is restored and online&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"8\">\n<li>Log into the controller node, preferably as a root<\/li>\n\n\n\n<li>Verify connection to a new db using psql or podman container. The syntax is like below, with the exception of the username (-U) and the database we are connecting to (the name can be found in the inventory file).&nbsp;<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;root@aapcontroller01 ~]# psql -h aapdb02.cbr8auhjg1vp.us-west-1.rds.amazonaws.com -U awx -d aapdb \n\nPassword for user awx: \n\npsql (13.7, server 12.10) \n\nSSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) \n\nType \"help\" for help. \n\n \n\naapdb=&gt; l \n\n                                  List of databases \n\n   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges    \n\n-----------+----------+----------+-------------+-------------+----------------------- \n\n aapdb     | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc\/postgres         + \n\n           |          |          |             |             | postgres=CTc\/postgres+ \n\n           |          |          |             |             | awx=CTc\/postgres \n\n aaphubdb  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc\/postgres         + \n\n           |          |          |             |             | postgres=CTc\/postgres+ \n\n           |          |          |             |             | awx=CTc\/postgres \n\n postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | \n\n rdsadmin  | rdsadmin | UTF8     | en_US.UTF-8 | en_US.UTF-8 | rdsadmin=CTc\/rdsadmin \n\n template0 | rdsadmin | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c\/rdsadmin          + \n\n           |          |          |             |             | rdsadmin=CTc\/rdsadmin \n\n template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c\/postgres          + \n\n           |          |          |             |             | postgres=CTc\/postgres \n\n(6 rows) \n\naapdb=&gt; <\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"10\">\n<li>Once connectivity has been confirmed, stop the services on all servers (controllers and hubs):<\/li>\n<\/ol>\n\n\n\n<p>Run the following command on controllers:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>automation-controller-service stop <\/code><\/pre>\n\n\n\n<p>Run the following command on the hubs:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Run the following command on the hubs: <\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"11\">\n<li>On controller nodes, change directory to: \/etc\/tower\/conf.d\/&nbsp;<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>cd \/etc\/tower\/conf.d <\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"12\">\n<li>Edit the postgres.py file and update the DB Host name on all controller nodes<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code> Ansible Automation Platform controller database settings. \n\n \n\nDATABASES = { \n\n   'default': { \n\n       'ATOMIC_REQUESTS': True, \n\n       'ENGINE': 'awx.main.db.profiled_pg', \n\n       'NAME': 'aapdb', \n\n       'USER': 'awx', \n\n       'PASSWORD': \"\"\"Password\"\"\", \n\n       'HOST': 'aapdb02.cbr8auhjg1vp.us-west-1.rds.amazonaws.com', \n\n       'PORT': '5432', \n\n       'OPTIONS': { 'sslmode': 'prefer', \n\n                    'sslrootcert': '\/etc\/pki\/tls\/certs\/ca-bundle.crt', \n\n       }, \n\n   } \n\n} <\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"13\">\n<li>On the hub nodes, change directory to \/etc\/pulp:&nbsp;<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>cd \/etc\/pulp <\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"14\">\n<li>Edit the settings.py file and update the database name in DATABASES section:&nbsp;<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>DATABASES = {'default': {'HOST': 'aapdb02.cbr8auhjg1vp.us-west-1.rds.amazonaws.com', 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'aaphubdb', 'USER': 'awx', 'PASSWORD': 'P@ssw0rd', 'PORT': 5432, 'OPTIONS': {'sslmode': 'prefer', 'sslrootcert': '\/etc\/pki\/tls\/certs\/ca-bundle.crt'}}} \n\nREDIS_HOST = 'localhost' \n\nREDIS_PORT = 6379 \n\nCACHE_ENABLED = True \n\nGALAXY_COLLECTION_SIGNING_SERVICE = 'ansible-default' \n\nPRIVATE_KEY_PATH = '\/etc\/pulp\/certs\/token_private_key.pem' \n\nPUBLIC_KEY_PATH = '\/etc\/pulp\/certs\/token_public_key.pem' \n\nTOKEN_SERVER = 'https:\/\/aaphub01.example.net\/token' \n\nTOKEN_SIGNATURE_ALGORITHM = 'ES256' \n\nALLOWED_CONTENT_CHECKSUMS = &#91;'sha224', 'sha256', 'sha384', 'sha512'] \n\nSECRET_KEY = 'REDUCTED' \n\nCONTENT_ORIGIN = 'https:\/\/aaphub01.example.net' \n\nX_PULP_API_PROTO = 'https' \n\nX_PULP_API_HOST = 'aaphub01.example.net' \n\nX_PULP_API_PORT = '443' \n\nX_PULP_API_PREFIX = 'pulp_ansible\/galaxy\/automation-hub\/api' \n\nGALAXY_API_DEFAULT_DISTRIBUTION_BASE_PATH = 'published' \n\nGALAXY_ENABLE_API_ACCESS_LOG = False \n\nGALAXY_ENABLE_UNAUTHENTICATED_COLLECTION_ACCESS = False \n\nGALAXY_ENABLE_UNAUTHENTICATED_COLLECTION_DOWNLOAD = False \n\nGALAXY_REQUIRE_CONTENT_APPROVAL = True \n\nGALAXY_AUTO_SIGN_COLLECTIONS = False \n\nREDIS_URL = 'unix:\/\/\/var\/run\/redis\/redis.sock' \n\nANSIBLE_API_HOSTNAME = 'https:\/\/aaphub01.example.net' \n\nANSIBLE_CONTENT_HOSTNAME = 'https:\/\/aaphub01.example.net' \n\nCONTENT_BIND = 'unix:\/var\/run\/pulpcore-content\/pulpcore-content.sock' \n\nCONNECTED_ANSIBLE_CONTROLLERS = &#91;'https:\/\/aapcontroller01.example.net', 'https:\/\/aapcontroller02.example.net'] \n\nDEPLOY_ROOT = \"\/var\/lib\/pulp\" \n\nMEDIA_ROOT = \"\/var\/lib\/pulp\/media\" \n\nSTATIC_ROOT = \"\/var\/lib\/pulp\/assets\" \n\nWORKING_DIRECTORY = \"\/var\/lib\/pulp\/tmp\" \n\nFILE_UPLOAD_TEMP_DIR = \"\/var\/lib\/pulp\/tmp\" \n\nDB_ENCRYPTION_KEY = \"\/etc\/pulp\/certs\/database_fields.symmetric.key\" <\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"15\">\n<li>Reboot the hub nodes&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"16\">\n<li>Start the service on all controller nodes:&nbsp;<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>automation-controller-service start <\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"17\">\n<li>On the controller node, run the following command as root. The command will verify the connection to the DB and connection between the controller nodes. All nodes should be visible and have the recent heartbeat timestamp:&nbsp;<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;root@aapcontroller01 ~]# awx-manage list_instances \n\n&#91;controlplane capacity=270 policy=100%] \n\naapcontroller01.example.net capacity=135 node_type=hybrid version=4.2.0 heartbeat=\"2022-06-23 05:44:45\" \n\naapcontroller02.example.net capacity=135 node_type=hybrid version=4.2.0 heartbeat=\"2022-06-23 05:44:44\" \n\n \n\n&#91;default capacity=270 policy=100%] \n\naapcontroller01.example.net capacity=135 node_type=hybrid version=4.2.0 heartbeat=\"2022-06-23 05:44:45\" \n\naapcontroller02.example.net capacity=135 node_type=hybrid version=4.2.0 heartbeat=\"2022-06-23 05:44:44\" <\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"18\">\n<li>Connect to each controller node using web browser and verify the communication and configuration&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\" start=\"19\">\n<li>Connect to each hub node using web browser and verify the communication and configuration&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>I hope this blog provided you with the necessary insights how to recover the database. Please note that the same process works for the AAP Database hosted in Azure.&nbsp;<\/p>\n\n\n\n<p>AAP with AWS RDS ensures disaster recovery success. Automated backups and failover guarantee continuous app availability and data protection. With its ease of use and flexible architecture, Ansible is the ideal tool for managing disaster recovery in the cloud.\u00a0 Get ahead of the curve with this flexible and easy-to-use solution. Want to learn more? <a href=\"https:\/\/www.insentragroup.com\/us\/contact\/\" target=\"_blank\" rel=\"noreferrer noopener\">Contact us<\/a> today!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Related Articles<\/h2>\n\n\n\n<a href=\"https:\/\/www.insentragroup.com\/us\/insights\/geek-speak\/cloud-and-modern-data-center\/azure-site-recovery-and-mcs-provisioned-workloads\/\" target=\"_blank\" rel=\"noreferrer noopener\">Azure Site Recovery and MCS Provisioned Workloads<\/a><br>\n<a href=\"https:\/\/www.insentragroup.com\/us\/insights\/geek-speak\/professional-services\/azure-disaster-recovery-and-backup\/\" target=\"_blank\" rel=\"noreferrer noopener\">Azure Disaster Recovery and Backup<\/a><br>\n<a href=\"https:\/\/www.insentragroup.com\/us\/insights\/geek-speak\/secure-workplace\/cia-triad-the-mother-of-data-security\/\" target=\"_blank\" rel=\"noreferrer noopener\">CIA Triad \u2013 The Mother of Data Security<\/a><br>\n<a href=\"https:\/\/www.insentragroup.com\/us\/insights\/geek-speak\/modern-workplace\/veritas-360-data-management\/\" target=\"_blank\" rel=\"noreferrer noopener\">Veritas 360 Data Management<\/a>\n\n\n\n<style>\nbody .wp-block-code>code {\n    font-family: Menlo,Consolas,monaco,monospace;\n    color: #000;\n    padding: 30px 40px;\n    border: none;\n    border-radius: 4px;\n    background: #ddd;\n}\nbody .blog-body ol li::marker {\n    font-weight: 600;\n}\n<\/style>\n","protected":false},"excerpt":{"rendered":"<p>Discover the benefits of AWS RDS Disaster Recovery for AAP. Learn how to automate data protection and ensure high availability for your applications with the power of cloud computing. Read our latest blog for complete details.<\/p>\n","protected":false},"author":67,"featured_media":15818,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"content-type":"","footnotes":""},"categories":[19],"tags":[],"class_list":["post-15811","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-workplace","entry"],"_links":{"self":[{"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/posts\/15811","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/users\/67"}],"replies":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/comments?post=15811"}],"version-history":[{"count":5,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/posts\/15811\/revisions"}],"predecessor-version":[{"id":21803,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/posts\/15811\/revisions\/21803"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/media\/15818"}],"wp:attachment":[{"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/media?parent=15811"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/categories?post=15811"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.insentragroup.com\/us\/wp-json\/wp\/v2\/tags?post=15811"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}