mirror of
https://github.com/Sea-Haven-Industries/file-share.git
synced 2026-09-30 07:43:17 +00:00
Some checks failed
Deploy / deploy (push) Has been cancelled
The README described the deployed AWS resources and how to deploy, but never documented that this is a CDK (infrastructure-as-code) app or what cdk.json is. Add an Infrastructure (CDK) section covering the app entry point, the file-share stack, the cdk.json manifest and context cache, and the synth/diff/deploy commands, so the IaC layer is discoverable.
99 lines
5.3 KiB
Markdown
99 lines
5.3 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 (CDK)
|
|
|
|
All infrastructure is defined as code with the [AWS CDK](https://docs.aws.amazon.com/cdk/) (TypeScript). The app synthesizes a single CloudFormation stack — `file-share` — that provisions everything described under [Architecture](#architecture), deployed to account `328440206208` in `us-east-1`.
|
|
|
|
```
|
|
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
|
|
|
|
```bash
|
|
npm install
|
|
npx cdk deploy
|
|
```
|
|
|
|
The stack outputs the instance's private IP for SMB and FileBrowser access.
|
|
|
|
## 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
|
|
```
|