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.
- lightsail_wordpress_migrator-1.0.0/LICENSE +21 -0
- lightsail_wordpress_migrator-1.0.0/PKG-INFO +221 -0
- lightsail_wordpress_migrator-1.0.0/README.md +190 -0
- lightsail_wordpress_migrator-1.0.0/pyproject.toml +58 -0
- lightsail_wordpress_migrator-1.0.0/setup.cfg +4 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/PKG-INFO +221 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/SOURCES.txt +20 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/dependency_links.txt +1 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/entry_points.txt +2 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/requires.txt +6 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wordpress_migrator.egg-info/top_level.txt +1 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/__init__.py +8 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/aws.py +357 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/cli.py +215 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/orchestrator.py +331 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/security.py +122 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/ssh.py +113 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/utils.py +66 -0
- lightsail_wordpress_migrator-1.0.0/src/lightsail_wp_migrate/wordpress.py +155 -0
- lightsail_wordpress_migrator-1.0.0/tests/test_cli.py +41 -0
- lightsail_wordpress_migrator-1.0.0/tests/test_security.py +27 -0
- 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
|
+
[](https://opensource.org/licenses/MIT)
|
|
35
|
+
[](https://www.python.org/downloads/)
|
|
36
|
+
[](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
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](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"]
|