lightsail-wordpress-migrator 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. lightsail_wordpress_migrator-1.0.0/LICENSE +21 -0
  2. lightsail_wordpress_migrator-1.0.0/PKG-INFO +221 -0
  3. lightsail_wordpress_migrator-1.0.0/README.md +190 -0
  4. lightsail_wordpress_migrator-1.0.0/pyproject.toml +58 -0
  5. lightsail_wordpress_migrator-1.0.0/setup.cfg +4 -0
  6. lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/PKG-INFO +221 -0
  7. lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/SOURCES.txt +20 -0
  8. lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/dependency_links.txt +1 -0
  9. lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/entry_points.txt +2 -0
  10. lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/requires.txt +6 -0
  11. lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/top_level.txt +1 -0
  12. lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/__init__.py +8 -0
  13. lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/aws.py +357 -0
  14. lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/cli.py +215 -0
  15. lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/orchestrator.py +331 -0
  16. lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/security.py +122 -0
  17. lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/ssh.py +113 -0
  18. lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/utils.py +66 -0
  19. lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/wordpress.py +155 -0
  20. lightsail_wordpress_migrator-1.0.0/tests/test_cli.py +41 -0
  21. lightsail_wordpress_migrator-1.0.0/tests/test_security.py +27 -0
  22. lightsail_wordpress_migrator-1.0.0/tests/test_wordpress.py +17 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jonathan Glass
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: lightsail-wordpress-migrator
3
+ Version: 1.0.0
4
+ Summary: Automated migration tool for upgrading AWS Lightsail Bitnami WordPress instances to modern Amazon Linux 2023 / Debian Lightsail blueprints.
5
+ Author: Jonathan Glass
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/jonathanbglass/lightsail-wordpress-migrator
8
+ Project-URL: Repository, https://github.com/jonathanbglass/lightsail-wordpress-migrator.git
9
+ Project-URL: Issues, https://github.com/jonathanbglass/lightsail-wordpress-migrator/issues
10
+ Keywords: aws,lightsail,wordpress,bitnami,migration,cloudwatch,fail2ban,devops
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: System Administrators
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: System :: Systems Administration
21
+ Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: boto3>=1.28.0
26
+ Requires-Dist: paramiko>=3.0.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
29
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # ๐Ÿš€ AWS Lightsail WordPress Migrator
33
+
34
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
35
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
36
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
37
+
38
+ An automated migration tool designed to upgrade legacy **Bitnami WordPress** Amazon Lightsail instances to modern **Amazon Linux 2023 / Debian Native Lightsail Blueprints** (`wordpress_ls_1_0`).
39
+
40
+ ---
41
+
42
+ ## ๐Ÿ“– The Problem
43
+
44
+ AWS Lightsail deprecated its legacy Bitnami WordPress blueprint in favor of a modern native stack running Debian/AL2023 with systemd, native MariaDB, and standard Apache.
45
+
46
+ Migrating manually is painful and error-prone because:
47
+ 1. **Incompatible Directory Layouts**: Legacy Bitnami uses `/opt/bitnami/...` and `ctlscript.sh`, whereas native instances use standard `/var/www/html` and `systemctl`.
48
+ 2. **Database Collation Incompatibilities**: MySQL 8.0 exports using `utf8mb4_0900_ai_ci` fail on target MariaDB databases without translation.
49
+ 3. **Apache Permalinks / `.htaccess` 404s**: Bitnami disables `.htaccess` runtime reading by default. When migrating to native Apache, missing `.htaccess` files break all subpages and return `404 Not Found`.
50
+ 4. **Dynamic Firewall Restrictions**: Managing temporary port 22 access without leaving SSH open permanently to `0.0.0.0/0`.
51
+ 5. **No IAM Instance Profiles on Lightsail**: Streaming server and application logs to CloudWatch requires provisioning dedicated minimal IAM credentials.
52
+
53
+ **Lightsail WordPress Migrator automates this entire lifecycle with zero manual database editing.**
54
+
55
+ ---
56
+
57
+ ## โœจ Features
58
+
59
+ - ๐Ÿ”„ **Full End-to-End Migration**: Automates database dump, `wp-content` archival, target instance provisioning, and data import.
60
+ - โšก **Direct S3 Transfer**: Uses presigned S3 URLs so high-volume assets transfer directly between Lightsail instances without routing through your local laptop.
61
+ - ๐Ÿ›ก๏ธ **Zero-Exposure Firewall Automation**: Dynamically opens port 22 for the runner's exact `/32` public IP, and **guarantees closure** via `finally` blocks upon completion or failure.
62
+ - ๐ŸŒ **Automated Static IP Cutover (`--reassign-static-ip`)**: Automatically discovers static IPs attached to the source, reassigns them to the target upon completion, and updates WordPress URLs for seamless DNS cutover.
63
+ - ๐Ÿ”ง **Collation Translation**: Automatically converts MySQL 8 collations (`utf8mb4_0900_ai_ci` / `utf8mb4_0900_as_cs`) to MariaDB-compatible `utf8mb4_unicode_520_ci`.
64
+ - ๐Ÿ“„ **Automatic `.htaccess` Generation**: Configures standard WordPress rewrite rules and `www-data` ownership to ensure flawless subpage permalink routing.
65
+ - ๐Ÿ”’ **Optional Security Hardening (`--harden-security`)**:
66
+ - **Fail2ban**: Deploys jails for SSH brute-force (`sshd`), WordPress login/XML-RPC defense (`apache-wplogin`), and vulnerability probe/traversal blocking (`apache-scanprobe`).
67
+ - **Apache Availability Hardening**: Deploys timeout and keepalive limits to protect small instances from slowloris / connection exhaustion attacks.
68
+ - ๐Ÿ“Š **Optional CloudWatch Ingestion (`--cloudwatch`)**: Provisions a dedicated least-privilege IAM user and configures `amazon-cloudwatch-agent` to stream Apache access/error logs, PHP-FPM, WordPress debug logs, and Fail2ban logs.
69
+ - ๐Ÿ” **Interactive Discovery & Dry-Run Mode**: Discovers running Lightsail instances and validates credentials, disk space, static IPs, and SSH keys before making any changes.
70
+
71
+ ---
72
+
73
+ ## ๐Ÿ› ๏ธ Architecture
74
+
75
+ ```
76
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
77
+ โ”‚ S3 Staging Bucket โ”‚
78
+ โ”‚ (Presigned Direct Link) โ”‚
79
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
80
+ โ”‚
81
+ 1. Export DB & Assets โ”‚ 2. Direct S3 Pull
82
+ โ”‚
83
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
84
+ โ”‚ Source Lightsail Host โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚ Target Lightsail Host โ”‚
85
+ โ”‚ (Legacy Bitnami / MySQL) โ”‚ โ”‚ (Native AL2023/Debian/Maria) โ”‚
86
+ โ”‚ โ”‚ โ”‚ โ”‚
87
+ โ”‚ โ€ข Bitnami stack detection โ”‚ โ”‚ โ€ข Collation normalization โ”‚
88
+ โ”‚ โ€ข Database dump via socket/TCPโ”‚ โ”‚ โ€ข Apache .htaccess generation โ”‚
89
+ โ”‚ โ€ข wp-content tarball โ”‚ โ”‚ โ€ข File permissions (www-data) โ”‚
90
+ โ”‚ โ€ข Pre-migration snapshot โ”‚ โ”‚ โ€ข Static IP cutover โ”‚
91
+ โ”‚ โ€ข Attached Static IP discoveryโ”‚ โ”‚ โ€ข Fail2ban & Security tuning โ”‚
92
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ€ข CloudWatch Logs agent โ”‚
93
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
94
+ ```
95
+
96
+ ---
97
+
98
+ ## ๐Ÿš€ Quick Start
99
+
100
+ ### 1. Installation
101
+
102
+ #### Option A: Clone & Run (Zero install)
103
+ ```bash
104
+ git clone https://github.com/jonathanbglass/lightsail-wordpress-migrator.git
105
+ cd lightsail-wordpress-migrator
106
+ pip install boto3 paramiko
107
+ ```
108
+
109
+ #### Option B: Install via pip
110
+ ```bash
111
+ pip install .
112
+ ```
113
+
114
+ ---
115
+
116
+ ### 2. Usage
117
+
118
+ #### Interactive Mode (Recommended)
119
+ If you don't pass arguments, the migrator interactively lists your instances, checks for attached static IPs, and prompts for confirmation:
120
+ ```bash
121
+ python migrate.py
122
+ # or if installed via pip:
123
+ lightsail-wp-migrate
124
+ ```
125
+
126
+ #### CLI One-Liner (Non-Interactive with Static IP Reassignment)
127
+ ```bash
128
+ python migrate.py \
129
+ --source "MyWordPressBitnami" \
130
+ --target "MyWordPress-Native" \
131
+ --profile default \
132
+ --region us-east-1 \
133
+ --reassign-static-ip \
134
+ --harden-security \
135
+ --cloudwatch \
136
+ --yes
137
+ ```
138
+
139
+ #### Safe Dry-Run (Pre-flight validation)
140
+ ```bash
141
+ python migrate.py \
142
+ --source "MyWordPressBitnami" \
143
+ --target "MyWordPress-Native" \
144
+ --dry-run
145
+ ```
146
+
147
+ ---
148
+
149
+ ## โš™๏ธ CLI Options Reference
150
+
151
+ | Flag | Default | Description |
152
+ | :--- | :--- | :--- |
153
+ | `--source`, `-s` | `None` | Name of existing Bitnami Lightsail instance (prompted if omitted). |
154
+ | `--target`, `-t` | `<source>-2` | Name of target Lightsail instance. |
155
+ | `--profile`, `-p` | `$AWS_PROFILE` or `default` | AWS CLI credential profile. |
156
+ | `--region`, `-r` | `$AWS_DEFAULT_REGION` or `us-east-1` | AWS region. |
157
+ | `--source-key` | Auto-discovered in `~/.ssh` | Path to source SSH private key (`.pem`). |
158
+ | `--target-key` | Source key | Path to target SSH private key (`.pem`). |
159
+ | `--bundle-id` | `nano_3_0` | Lightsail bundle size (e.g. `nano_3_0`, `micro_3_0`, `small_3_0`). |
160
+ | `--s3-bucket` | Auto-derived | S3 bucket for staging transfer artifacts. |
161
+ | `--snapshot / --no-snapshot` | `True` | Create a pre-migration snapshot of source. |
162
+ | `--reassign-static-ip` | `False` | Automatically detach static IP from source and attach to target upon migration completion. |
163
+ | `--static-ip` | `Auto-detect` | Explicit name of Lightsail Static IP to reassign. |
164
+ | `--harden-security / --no-harden-security` | `True` | Install and configure Fail2ban and Apache availability protections. |
165
+ | `--cloudwatch` | `False` | Provision IAM user and stream logs to CloudWatch. |
166
+ | `--dry-run` | `False` | Test credentials, inspect instances, and verify static IPs without making changes. |
167
+ | `--yes`, `-y` | `False` | Skip interactive confirmation prompts. |
168
+ | `--verbose`, `-v` | `False` | Enable debug logging output. |
169
+
170
+ ---
171
+
172
+ ## ๐Ÿ”’ Security Hardening Details
173
+
174
+ When `--harden-security` is enabled (default), the following defenses are provisioned on the target:
175
+
176
+ 1. **Fail2ban Jails (`/etc/fail2ban/jail.local`)**:
177
+ - `sshd`: Systemd backend, max 5 retries, 1-hour ban.
178
+ - `apache-wplogin`: Rate limits `wp-login.php` and `xmlrpc.php` brute force (max 8 attempts in 5 mins -> 1-hour ban).
179
+ - `apache-scanprobe`: Blocks automated vulnerability scanners querying `.env`, `.git`, `wp-config.php`, `phpmyadmin`, or directory traversal (5 attempts -> 6-hour ban).
180
+ 2. **Apache Availability Limits (`/etc/apache2/conf-available/availability-hardening.conf`)**:
181
+ - Caps `Timeout 60`, `KeepAliveTimeout 2`, and `MaxKeepAliveRequests 50` to safeguard low-memory / 2 vCPU Lightsail instances from connection exhaustion.
182
+
183
+ ---
184
+
185
+ ## ๐Ÿ“‹ Post-Migration Checklist
186
+
187
+ After migration completes:
188
+
189
+ 1. **Verify Website & Permalinks**: Open `http://<TARGET_IP_OR_STATIC_IP>` and click several subpages to confirm `.htaccess` routing works.
190
+ 2. **Verify WordPress Admin**: Log into `http://<TARGET_IP_OR_STATIC_IP>/wp-admin` to confirm all plugins, themes, and media uploads are present.
191
+ 3. **DNS & Static IP**:
192
+ - If `--reassign-static-ip` was used, the static IP is already attached to the new target. Ensure your DNS `A` records point to it.
193
+ - Otherwise, attach a static IP in the AWS Lightsail console and update DNS.
194
+ 4. **Issue Free SSL via Let's Encrypt**:
195
+ Once your domain resolves to the new instance, run standard Certbot:
196
+ ```bash
197
+ sudo apt-get update
198
+ sudo apt-get install -y certbot python3-certbot-apache
199
+ sudo certbot --apache
200
+ ```
201
+ 5. **Retire Old Instance**: Once verified, stop or delete the old Bitnami instance.
202
+
203
+ ---
204
+
205
+ ## ๐Ÿงช Testing
206
+
207
+ Run the test suite with Python's built-in `unittest` runner:
208
+ ```bash
209
+ python -m unittest discover -s tests
210
+ ```
211
+
212
+ Or with `pytest`:
213
+ ```bash
214
+ pytest tests/
215
+ ```
216
+
217
+ ---
218
+
219
+ ## ๐Ÿ“„ License
220
+
221
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,190 @@
1
+ # ๐Ÿš€ AWS Lightsail WordPress Migrator
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
5
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
6
+
7
+ An automated migration tool designed to upgrade legacy **Bitnami WordPress** Amazon Lightsail instances to modern **Amazon Linux 2023 / Debian Native Lightsail Blueprints** (`wordpress_ls_1_0`).
8
+
9
+ ---
10
+
11
+ ## ๐Ÿ“– The Problem
12
+
13
+ AWS Lightsail deprecated its legacy Bitnami WordPress blueprint in favor of a modern native stack running Debian/AL2023 with systemd, native MariaDB, and standard Apache.
14
+
15
+ Migrating manually is painful and error-prone because:
16
+ 1. **Incompatible Directory Layouts**: Legacy Bitnami uses `/opt/bitnami/...` and `ctlscript.sh`, whereas native instances use standard `/var/www/html` and `systemctl`.
17
+ 2. **Database Collation Incompatibilities**: MySQL 8.0 exports using `utf8mb4_0900_ai_ci` fail on target MariaDB databases without translation.
18
+ 3. **Apache Permalinks / `.htaccess` 404s**: Bitnami disables `.htaccess` runtime reading by default. When migrating to native Apache, missing `.htaccess` files break all subpages and return `404 Not Found`.
19
+ 4. **Dynamic Firewall Restrictions**: Managing temporary port 22 access without leaving SSH open permanently to `0.0.0.0/0`.
20
+ 5. **No IAM Instance Profiles on Lightsail**: Streaming server and application logs to CloudWatch requires provisioning dedicated minimal IAM credentials.
21
+
22
+ **Lightsail WordPress Migrator automates this entire lifecycle with zero manual database editing.**
23
+
24
+ ---
25
+
26
+ ## โœจ Features
27
+
28
+ - ๐Ÿ”„ **Full End-to-End Migration**: Automates database dump, `wp-content` archival, target instance provisioning, and data import.
29
+ - โšก **Direct S3 Transfer**: Uses presigned S3 URLs so high-volume assets transfer directly between Lightsail instances without routing through your local laptop.
30
+ - ๐Ÿ›ก๏ธ **Zero-Exposure Firewall Automation**: Dynamically opens port 22 for the runner's exact `/32` public IP, and **guarantees closure** via `finally` blocks upon completion or failure.
31
+ - ๐ŸŒ **Automated Static IP Cutover (`--reassign-static-ip`)**: Automatically discovers static IPs attached to the source, reassigns them to the target upon completion, and updates WordPress URLs for seamless DNS cutover.
32
+ - ๐Ÿ”ง **Collation Translation**: Automatically converts MySQL 8 collations (`utf8mb4_0900_ai_ci` / `utf8mb4_0900_as_cs`) to MariaDB-compatible `utf8mb4_unicode_520_ci`.
33
+ - ๐Ÿ“„ **Automatic `.htaccess` Generation**: Configures standard WordPress rewrite rules and `www-data` ownership to ensure flawless subpage permalink routing.
34
+ - ๐Ÿ”’ **Optional Security Hardening (`--harden-security`)**:
35
+ - **Fail2ban**: Deploys jails for SSH brute-force (`sshd`), WordPress login/XML-RPC defense (`apache-wplogin`), and vulnerability probe/traversal blocking (`apache-scanprobe`).
36
+ - **Apache Availability Hardening**: Deploys timeout and keepalive limits to protect small instances from slowloris / connection exhaustion attacks.
37
+ - ๐Ÿ“Š **Optional CloudWatch Ingestion (`--cloudwatch`)**: Provisions a dedicated least-privilege IAM user and configures `amazon-cloudwatch-agent` to stream Apache access/error logs, PHP-FPM, WordPress debug logs, and Fail2ban logs.
38
+ - ๐Ÿ” **Interactive Discovery & Dry-Run Mode**: Discovers running Lightsail instances and validates credentials, disk space, static IPs, and SSH keys before making any changes.
39
+
40
+ ---
41
+
42
+ ## ๐Ÿ› ๏ธ Architecture
43
+
44
+ ```
45
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
46
+ โ”‚ S3 Staging Bucket โ”‚
47
+ โ”‚ (Presigned Direct Link) โ”‚
48
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
49
+ โ”‚
50
+ 1. Export DB & Assets โ”‚ 2. Direct S3 Pull
51
+ โ”‚
52
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
53
+ โ”‚ Source Lightsail Host โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚ Target Lightsail Host โ”‚
54
+ โ”‚ (Legacy Bitnami / MySQL) โ”‚ โ”‚ (Native AL2023/Debian/Maria) โ”‚
55
+ โ”‚ โ”‚ โ”‚ โ”‚
56
+ โ”‚ โ€ข Bitnami stack detection โ”‚ โ”‚ โ€ข Collation normalization โ”‚
57
+ โ”‚ โ€ข Database dump via socket/TCPโ”‚ โ”‚ โ€ข Apache .htaccess generation โ”‚
58
+ โ”‚ โ€ข wp-content tarball โ”‚ โ”‚ โ€ข File permissions (www-data) โ”‚
59
+ โ”‚ โ€ข Pre-migration snapshot โ”‚ โ”‚ โ€ข Static IP cutover โ”‚
60
+ โ”‚ โ€ข Attached Static IP discoveryโ”‚ โ”‚ โ€ข Fail2ban & Security tuning โ”‚
61
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ€ข CloudWatch Logs agent โ”‚
62
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
63
+ ```
64
+
65
+ ---
66
+
67
+ ## ๐Ÿš€ Quick Start
68
+
69
+ ### 1. Installation
70
+
71
+ #### Option A: Clone & Run (Zero install)
72
+ ```bash
73
+ git clone https://github.com/jonathanbglass/lightsail-wordpress-migrator.git
74
+ cd lightsail-wordpress-migrator
75
+ pip install boto3 paramiko
76
+ ```
77
+
78
+ #### Option B: Install via pip
79
+ ```bash
80
+ pip install .
81
+ ```
82
+
83
+ ---
84
+
85
+ ### 2. Usage
86
+
87
+ #### Interactive Mode (Recommended)
88
+ If you don't pass arguments, the migrator interactively lists your instances, checks for attached static IPs, and prompts for confirmation:
89
+ ```bash
90
+ python migrate.py
91
+ # or if installed via pip:
92
+ lightsail-wp-migrate
93
+ ```
94
+
95
+ #### CLI One-Liner (Non-Interactive with Static IP Reassignment)
96
+ ```bash
97
+ python migrate.py \
98
+ --source "MyWordPressBitnami" \
99
+ --target "MyWordPress-Native" \
100
+ --profile default \
101
+ --region us-east-1 \
102
+ --reassign-static-ip \
103
+ --harden-security \
104
+ --cloudwatch \
105
+ --yes
106
+ ```
107
+
108
+ #### Safe Dry-Run (Pre-flight validation)
109
+ ```bash
110
+ python migrate.py \
111
+ --source "MyWordPressBitnami" \
112
+ --target "MyWordPress-Native" \
113
+ --dry-run
114
+ ```
115
+
116
+ ---
117
+
118
+ ## โš™๏ธ CLI Options Reference
119
+
120
+ | Flag | Default | Description |
121
+ | :--- | :--- | :--- |
122
+ | `--source`, `-s` | `None` | Name of existing Bitnami Lightsail instance (prompted if omitted). |
123
+ | `--target`, `-t` | `<source>-2` | Name of target Lightsail instance. |
124
+ | `--profile`, `-p` | `$AWS_PROFILE` or `default` | AWS CLI credential profile. |
125
+ | `--region`, `-r` | `$AWS_DEFAULT_REGION` or `us-east-1` | AWS region. |
126
+ | `--source-key` | Auto-discovered in `~/.ssh` | Path to source SSH private key (`.pem`). |
127
+ | `--target-key` | Source key | Path to target SSH private key (`.pem`). |
128
+ | `--bundle-id` | `nano_3_0` | Lightsail bundle size (e.g. `nano_3_0`, `micro_3_0`, `small_3_0`). |
129
+ | `--s3-bucket` | Auto-derived | S3 bucket for staging transfer artifacts. |
130
+ | `--snapshot / --no-snapshot` | `True` | Create a pre-migration snapshot of source. |
131
+ | `--reassign-static-ip` | `False` | Automatically detach static IP from source and attach to target upon migration completion. |
132
+ | `--static-ip` | `Auto-detect` | Explicit name of Lightsail Static IP to reassign. |
133
+ | `--harden-security / --no-harden-security` | `True` | Install and configure Fail2ban and Apache availability protections. |
134
+ | `--cloudwatch` | `False` | Provision IAM user and stream logs to CloudWatch. |
135
+ | `--dry-run` | `False` | Test credentials, inspect instances, and verify static IPs without making changes. |
136
+ | `--yes`, `-y` | `False` | Skip interactive confirmation prompts. |
137
+ | `--verbose`, `-v` | `False` | Enable debug logging output. |
138
+
139
+ ---
140
+
141
+ ## ๐Ÿ”’ Security Hardening Details
142
+
143
+ When `--harden-security` is enabled (default), the following defenses are provisioned on the target:
144
+
145
+ 1. **Fail2ban Jails (`/etc/fail2ban/jail.local`)**:
146
+ - `sshd`: Systemd backend, max 5 retries, 1-hour ban.
147
+ - `apache-wplogin`: Rate limits `wp-login.php` and `xmlrpc.php` brute force (max 8 attempts in 5 mins -> 1-hour ban).
148
+ - `apache-scanprobe`: Blocks automated vulnerability scanners querying `.env`, `.git`, `wp-config.php`, `phpmyadmin`, or directory traversal (5 attempts -> 6-hour ban).
149
+ 2. **Apache Availability Limits (`/etc/apache2/conf-available/availability-hardening.conf`)**:
150
+ - Caps `Timeout 60`, `KeepAliveTimeout 2`, and `MaxKeepAliveRequests 50` to safeguard low-memory / 2 vCPU Lightsail instances from connection exhaustion.
151
+
152
+ ---
153
+
154
+ ## ๐Ÿ“‹ Post-Migration Checklist
155
+
156
+ After migration completes:
157
+
158
+ 1. **Verify Website & Permalinks**: Open `http://<TARGET_IP_OR_STATIC_IP>` and click several subpages to confirm `.htaccess` routing works.
159
+ 2. **Verify WordPress Admin**: Log into `http://<TARGET_IP_OR_STATIC_IP>/wp-admin` to confirm all plugins, themes, and media uploads are present.
160
+ 3. **DNS & Static IP**:
161
+ - If `--reassign-static-ip` was used, the static IP is already attached to the new target. Ensure your DNS `A` records point to it.
162
+ - Otherwise, attach a static IP in the AWS Lightsail console and update DNS.
163
+ 4. **Issue Free SSL via Let's Encrypt**:
164
+ Once your domain resolves to the new instance, run standard Certbot:
165
+ ```bash
166
+ sudo apt-get update
167
+ sudo apt-get install -y certbot python3-certbot-apache
168
+ sudo certbot --apache
169
+ ```
170
+ 5. **Retire Old Instance**: Once verified, stop or delete the old Bitnami instance.
171
+
172
+ ---
173
+
174
+ ## ๐Ÿงช Testing
175
+
176
+ Run the test suite with Python's built-in `unittest` runner:
177
+ ```bash
178
+ python -m unittest discover -s tests
179
+ ```
180
+
181
+ Or with `pytest`:
182
+ ```bash
183
+ pytest tests/
184
+ ```
185
+
186
+ ---
187
+
188
+ ## ๐Ÿ“„ License
189
+
190
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,58 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "lightsail-wordpress-migrator"
7
+ version = "1.0.0"
8
+ description = "Automated migration tool for upgrading AWS Lightsail Bitnami WordPress instances to modern Amazon Linux 2023 / Debian Lightsail blueprints."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Jonathan Glass" }
14
+ ]
15
+ keywords = [
16
+ "aws",
17
+ "lightsail",
18
+ "wordpress",
19
+ "bitnami",
20
+ "migration",
21
+ "cloudwatch",
22
+ "fail2ban",
23
+ "devops"
24
+ ]
25
+ classifiers = [
26
+ "Development Status :: 5 - Production/Stable",
27
+ "Intended Audience :: System Administrators",
28
+ "Intended Audience :: Developers",
29
+ "License :: OSI Approved :: MIT License",
30
+ "Programming Language :: Python :: 3",
31
+ "Programming Language :: Python :: 3.9",
32
+ "Programming Language :: Python :: 3.10",
33
+ "Programming Language :: Python :: 3.11",
34
+ "Programming Language :: Python :: 3.12",
35
+ "Topic :: System :: Systems Administration",
36
+ "Topic :: Internet :: WWW/HTTP :: Site Management",
37
+ ]
38
+ dependencies = [
39
+ "boto3>=1.28.0",
40
+ "paramiko>=3.0.0",
41
+ ]
42
+
43
+ [project.optional-dependencies]
44
+ dev = [
45
+ "pytest>=7.0.0",
46
+ "ruff>=0.1.0",
47
+ ]
48
+
49
+ [project.scripts]
50
+ lightsail-wp-migrate = "lightsail_wp_migrate.cli:main"
51
+
52
+ [project.urls]
53
+ Homepage = "https://github.com/jonathanbglass/lightsail-wordpress-migrator"
54
+ Repository = "https://github.com/jonathanbglass/lightsail-wordpress-migrator.git"
55
+ Issues = "https://github.com/jonathanbglass/lightsail-wordpress-migrator/issues"
56
+
57
+ [tool.setuptools.packages.find]
58
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+