mirror of
https://github.com/Sea-Haven-Industries/file-share.git
synced 2026-09-30 05:33:10 +00:00
* fix(infra): look up the live office VPN gateway (PLAT-77) The gateway tagged syslog-server-office is deleted, so the plan cannot find a route target for the office LANs. * fix(infra): select the office VPN gateway by id (PLAT-77) A state-and-VPC lookup is not unique once syslog recreates its deleted gateway. The workspace variable pins the gateway that is carrying office traffic.
105 lines
6.5 KiB
Markdown
105 lines
6.5 KiB
Markdown
# file-share
|
|
|
|

|
|

|
|

|
|
|
|
Personal file share server on AWS — Samba for macOS Finder integration and FileBrowser for web-based file management. Accessible exclusively over the site-to-site VPN.
|
|
|
|
## Infrastructure
|
|
|
|
The live share is still the management-account CDK stack until cutover proof. The prod replacement is HCP Terraform in `terraform/`, workspace `file-share-prod`, trigger `terraform/**`. CDK deploy on push to main is frozen.
|
|
|
|
| Path | Role |
|
|
|---|---|
|
|
| `terraform/` | Prod EC2, subnet in the syslog VPC, DLM, and HCP roles |
|
|
| `lib/file-share-stack.ts` | Management-account CDK stack, still the live path until decommission |
|
|
|
|
```
|
|
bin/app.ts # CDK app entry point — instantiates the stack
|
|
lib/file-share-stack.ts # FileShareStack — all resource definitions
|
|
cdk.json # App command + CDK feature flags / context
|
|
cdk.context.json # Cached VPC/subnet lookups and the resolved AL2023 AMI
|
|
```
|
|
|
|
`cdk.json` is the CDK app manifest. Its `app` command (`npx tsx bin/app.ts`) runs the TypeScript entry point directly via [tsx](https://github.com/privatenumber/tsx) — no separate compile step is needed for synth or deploy. `bin/app.ts` instantiates `FileShareStack` with an explicit `stackName: "file-share"` (kebab-case, per convention) and the target account/region.
|
|
|
|
`aws-cdk-lib` is pinned to an exact version (`2.261.0`); the `aws-cdk` CLI is available as a dev dependency and via `npx cdk`.
|
|
|
|
Common commands (also exposed as npm scripts):
|
|
|
|
| Command | Purpose |
|
|
|---|---|
|
|
| `npx cdk synth` (`npm run synth`) | Synthesize the CloudFormation template to `cdk.out/` |
|
|
| `npx cdk diff` (`npm run diff`) | Diff the synthesized stack against what is deployed |
|
|
| `npx cdk deploy` (`npm run deploy`) | Deploy the stack |
|
|
| `npm run build` | Type-check via `tsc` |
|
|
|
|
## Architecture
|
|
|
|
- **EC2** — `t4g.small` (ARM64, Amazon Linux 2023) in the private subnet. The AMI is cached in the committed `cdk.context.json` (`cachedInContext: true`), so deploys never pick up a new AL2023 release implicitly — an AMI change forces instance replacement and must be deliberate (`cdk context --reset <ami key> && cdk synth`).
|
|
- **Samba** — SMB file share at `/data/share`, optimized for macOS (`vfs_fruit`)
|
|
- **FileBrowser** — Web UI on port 8080, backed by the same `/data/share` directory
|
|
- **SFTP** — password auth for user `adam` (`ForceCommand internal-sftp`, same password as SMB); used by Hazel for automated uploads
|
|
- **EBS data volume** — `vol-04d951cccacc435b5`, 500 GiB gp3 encrypted, mounted at `/data`. **Unmanaged import**: the stack references it by ID (`Volume.fromVolumeAttributes` + `CfnVolumeAttachment`), so CloudFormation can attach it but can never create, replace, or delete it — the data survives instance replacement and even stack deletion. UserData waits for the attachment, then mounts the existing filesystem; a `blkid` guard ensures a disk that already has a filesystem is never formatted.
|
|
- **DLM** — Daily EBS snapshots at 06:00 UTC, 30-day retention (targets the `file-share-backup=true` tag, set directly on the volume)
|
|
- **SSM** — Session Manager for instance access (no SSH key)
|
|
|
|
> **History:** the data volume was originally an inline `blockDevice`, which destroyed data on instance replacement (2026-05-27 incident), then a stack-managed standalone volume, which was orphaned when an uncommitted deploy got reverted by CD (2026-06-05 incident). The unmanaged-import design ends that failure class.
|
|
|
|
## Documentation
|
|
|
|
The canonical map of Sea Haven's AWS infrastructure lives in Confluence. This project's `file-share` stack is represented there as a Mermaid subgraph.
|
|
|
|
- **[AWS Architecture Map](https://seahaven.atlassian.net/wiki/spaces/IT/pages/1540098)** (Confluence, IT space, page 1540098)
|
|
|
|
## Access
|
|
|
|
Requires VPN connection to the office network (10.10.0.0/16).
|
|
|
|
### Finder (SMB)
|
|
|
|
1. Finder > Go > Connect to Server
|
|
2. Enter `smb://<private-ip>/files`
|
|
3. Authenticate with `adam` and the password from `file-share/smb-password` in Secrets Manager
|
|
|
|
### FileBrowser (Web)
|
|
|
|
Open `http://<private-ip>:8080` in a browser.
|
|
|
|
## Secrets
|
|
|
|
Both stored in AWS Secrets Manager:
|
|
|
|
| Secret | Purpose |
|
|
|---|---|
|
|
| `file-share/smb-password` | Samba user password |
|
|
| `file-share/filebrowser-password` | FileBrowser admin password |
|
|
|
|
Create these secrets before deploying the stack:
|
|
|
|
```bash
|
|
aws secretsmanager create-secret --name file-share/smb-password --secret-string '<password>'
|
|
aws secretsmanager create-secret --name file-share/filebrowser-password --secret-string '<password>'
|
|
```
|
|
|
|
## Deploy
|
|
|
|
Prod changes go through HCP Terraform workspace `file-share-prod` (manual apply until the move is sealed). The bootstrap apply creates the HCP roles and the instance boundary. The following apply, using `hcptf-file-share`, creates the subnet, security group, and DLM policy. `data_volume_id` stays empty until the snapshot copy exists, so those applies do not boot an instance.
|
|
|
|
The management-account CDK workflow no longer runs on push. `workflow_dispatch` remains for an explicit rollback of that stack.
|
|
|
|
The instance has no public IP. Its route table sends `10.10.0.0/16` and `10.30.0.0/16` through the VPN gateway in workspace variable `vpn_gateway_id` and everything else through a NAT gateway in the syslog public subnet. `10.10.0.0/16` is the Ronkonkoma office LAN and `10.30.0.0/16` is the Locust office LAN, the same pair the syslog VPN already routes. `10.20.0.0/16` is the management VPC and is not routed here.
|
|
|
|
Clients use the private IP. Office routing must include `10.40.20.0/24` on the existing syslog IPsec before SMB from the office will work. A check from `10.10.70.0/24` on 2026-09-28 reached the gateway for `10.40.10.254` and got no hop-1 reply for `10.40.20.1`. The nightly DLM policy targets volumes tagged `file-share-backup=true`. Tag the copied volume with that key at cutover.
|
|
|
|
## Expanding Storage
|
|
|
|
The data volume is **not managed by CloudFormation** (imported by ID), so changing a size in `lib/file-share-stack.ts` has no effect. Expand it directly — no downtime:
|
|
|
|
1. `aws ec2 modify-volume --volume-id vol-04d951cccacc435b5 --size <new-GiB>`
|
|
2. Wait for the modification to leave `modifying`: `aws ec2 describe-volumes-modifications --volume-ids vol-04d951cccacc435b5`
|
|
3. Resize the filesystem via an SSM session:
|
|
```bash
|
|
sudo resize2fs /dev/nvme1n1 # xvdf surfaces as nvme1n1 on Nitro instances
|
|
```
|