diff --git a/README.md b/README.md index 66c0035..a2eeb08 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ # ConfigDev -**[https://configdev.com/](https://configdev.com/)** +**Live site: [https://configdev.com](https://configdev.com)** -**Modern, client-side developer utilities for DevOps engineers, cloud architects, and SREs.** - -ConfigDev is a suite of zero-latency, privacy-first tools that solve everyday infrastructure problems without compromising data security. All processing runs 100% inside your browser — no uploads, no server round-trips, no logs. +Modern, client-side developer utilities for DevOps engineers, cloud architects, SREs, and backend developers. Every tool runs entirely inside the browser — no uploads, no server round-trips, no data egress. --- @@ -47,35 +45,30 @@ ConfigDev eliminates this entirely: --- -## Tech Stack +## Architecture -| Layer | Technology | -|---|---| -| Framework | [Astro](https://astro.build/) v7 — static output, zero-JS by default | -| UI Components | React 19 (islands, `client:load`) | -| Styling | Tailwind CSS v4 | -| Deployment | Cloudflare Pages | -| Sitemap | `@astrojs/sitemap` | +All tools follow the same pattern: a static Astro page wraps a React component mounted with `client:load`. The Astro layer handles all static output — layout, SEO metadata, JSON-LD structured data, educational content, and FAQ sections. The React component handles all interactive state — inputs, transformations, copy/download actions. ---- +No tool makes any outbound network request after page load. Transformations use only browser-native APIs: `btoa`, `atob`, `TextEncoder`, `URL`, `FileReader`, `Blob`. You can verify this by opening DevTools Network tab while using any tool. -## Development +### CIDR Programmatic Routes -```bash -# Install dependencies -npm install +The CIDR Subnet Calculator generates a static detail page for every IPv4 prefix from `/3` to `/32` using Astro's `getStaticPaths`. Each page at `/cidr-subnet-calculator/[n]-subnet` is pre-rendered at build time from `src/data/cidr-subnets.json`, which contains pre-computed values for each prefix: subnet mask, binary mask, usable host count, AWS reserved IP count, default range seed, common use case, and a ready-to-copy Terraform block. -# Start dev server -npm run dev +The `CIDRCalculator` component accepts optional `defaultIp` and `defaultCidr` props so each detail page pre-loads the calculator with the correct seed values for that prefix. -# Type-check and lint -npm run lint +--- -# Production build -npm run build -``` +## Tech Stack -The project uses flat file routing (`build.format: 'file'`), so pages emit as `/page-name.html` rather than `/page-name/index.html`. This eliminates the trailing-slash duplicate-URL issue in Google Search Console. +| Layer | Choice | +|---|---| +| Framework | [Astro](https://astro.build/) v7 — static output, zero-JS by default | +| Interactive components | React 19 with `client:load` hydration | +| Styling | Tailwind CSS v4 | +| Deployment | Cloudflare Pages | +| Sitemap | `@astrojs/sitemap` with per-page priority config | +| Type checking | TypeScript via `@astrojs/check` | --- @@ -85,56 +78,141 @@ The project uses flat file routing (`build.format: 'file'`), so pages emit as `/ src/ ├── components/ │ ├── shared/ -│ │ ├── Navbar.astro # Site-wide navigation with grouped tool categories +│ │ ├── Navbar.astro # Site-wide nav, tools grouped by category │ │ ├── Footer.astro -│ │ └── RelatedTools.astro # Cross-linking widget used on all tool pages +│ │ └── RelatedTools.astro # Cross-linking widget on every tool page │ └── tools/ -│ ├── CIDRCalculator.tsx +│ ├── CIDRCalculator.tsx # Accepts defaultIp, defaultCidr, subnet props │ ├── CronToSystemd.tsx │ ├── CsvToSchema.tsx │ ├── EnvToJson.tsx │ ├── JsonToEnv.tsx │ ├── K8sManifestSanitizer.tsx │ └── PiiScrubber.tsx +├── data/ +│ └── cidr-subnets.json # Pre-computed specs for all /3-/32 prefixes ├── layouts/ -│ └── Layout.astro # Base HTML shell, meta, canonical, JSON-LD +│ └── Layout.astro # HTML shell, canonical URL, meta tags, GA/Yandex ├── pages/ -│ ├── index.astro # Homepage with category grid and search/filter +│ ├── index.astro # Homepage: category grid, search/filter tabs +│ ├── cidr-subnet-calculator.astro +│ ├── cidr-subnet-calculator/ +│ │ └── [subnet]-subnet.astro # Generates /3-subnet through /32-subnet at build time │ ├── k8s-manifest-sanitizer.astro │ ├── pii-masker-log-scrubber.astro -│ ├── cidr-subnet-calculator.astro │ ├── cron-to-systemd-converter.astro │ ├── csv-to-json-schema.astro │ ├── env-to-json.astro │ ├── json-to-env.astro -│ └── ... +│ ├── about-us.astro +│ ├── contact.astro +│ ├── privacy.astro +│ ├── terms.astro +│ ├── 404.astro +│ └── 500.astro └── styles/ └── global.css public/ -├── robots.txt # Crawl directives — error/legal pages blocked -├── llms.txt # LLM-readable site manifest -└── _redirects # Cloudflare Pages redirect rules -astro.config.mjs # Site config, sitemap priorities, build format +├── robots.txt # Crawl directives, error/legal pages blocked +├── llms.txt # LLM-readable tool manifest +├── _redirects # Cloudflare Pages redirect rules +├── favicon.svg +└── icon.png +astro.config.mjs # Site URL, sitemap priorities, build format, integrations ``` --- -## Deployment +## Development + +**Prerequisites:** Node.js >= 20.0.0 + +```bash +# Install dependencies +npm install + +# Start local dev server (http://localhost:4321) +npm run dev + +# Type-check all Astro and TSX files +npm run lint -Configured for Cloudflare Pages. Set environment variables in your Pages dashboard before deploying: +# Production build (outputs to dist/) +npm run build + +# Preview production build locally +npm run preview +``` + +The build emits flat `.html` files (`/page-name.html`, not `/page-name/index.html`) because `build.format` is set to `file` in `astro.config.mjs`. This eliminates the trailing-slash duplicate URL problem in Google Search Console. + +--- + +## Environment Variables + +Copy `.env.example` to `.env` and fill in values as needed. Both variables are optional — the site builds and runs fully without them. + +```bash +cp .env.example .env +``` | Variable | Purpose | |---|---| -| `PUBLIC_GA_ID` | Google Analytics measurement ID (optional) | -| `PUBLIC_YANDEX_VERIFICATION` | Yandex Webmaster verification (optional) | +| `PUBLIC_GA_ID` | Google Analytics 4 measurement ID (e.g. `G-XXXXXXXXXX`) | +| `PUBLIC_YANDEX_VERIFICATION` | Yandex Webmaster verification token | + +These are injected into `Layout.astro` at build time via `import.meta.env`. The `PUBLIC_` prefix makes them safe for client-side exposure in Astro. + +--- + +## Deployment + +The project deploys to Cloudflare Pages. + +- Build command: `npm run build` +- Output directory: `dist/` +- Node version: 22 + +Set `PUBLIC_GA_ID` and `PUBLIC_YANDEX_VERIFICATION` in the Cloudflare Pages environment variables dashboard if needed. + +Manual deploy via Wrangler: + +```bash +npm run deploy +``` + +This runs `wrangler pages deploy dist --project-name configdev --commit-dirty=true`. + +--- + +## CI Pipeline + +GitHub Actions runs on every push to `main` and every pull request targeting `main`. + +Two jobs run sequentially: + +1. **Lint** — runs `npm run lint` (`astro check`) to catch type errors and Astro diagnostics +2. **Build** — runs `npm run build` after lint passes; uploads `dist/` as an artifact (7-day retention) + +Both jobs use Node 22 and `npm ci` for reproducible installs. In-progress runs for the same branch are cancelled when new commits arrive. + +--- + +## SEO & Crawlability -Deploy command: `npm run build` → output directory: `dist/` +- Sitemap generated at `/sitemap-index.xml` by `@astrojs/sitemap` +- All 7 tool pages: `priority 1.0`, `changefreq weekly` +- Homepage and about: `priority 0.8`, `changefreq monthly` +- Error pages (`/404`, `/500`) and legal pages (`/terms`, `/privacy`, `/contact`) excluded from sitemap and blocked in `robots.txt` +- Every tool page includes JSON-LD structured data: `WebApplication`, `FAQPage`, and `BreadcrumbList` +- CIDR detail pages include `TechArticle`, `WebApplication`, and `BreadcrumbList` structured data +- Canonical URLs set via `` in `Layout.astro` --- ## Contributing -See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. +See [CONTRIBUTING.md](CONTRIBUTING.md). --- diff --git a/src/components/tools/CIDRCalculator.tsx b/src/components/tools/CIDRCalculator.tsx index fb2c331..05615bf 100644 --- a/src/components/tools/CIDRCalculator.tsx +++ b/src/components/tools/CIDRCalculator.tsx @@ -20,9 +20,20 @@ interface CloudTemplate { description: string; } -export default function CIDRCalculator() { - const [ipInput, setIpInput] = useState('10.0.0.0'); - const [cidrInput, setCidrInput] = useState(16); +interface CIDRCalculatorProps { + defaultIp?: string; + defaultCidr?: number; + subnet?: number | string; +} + +export default function CIDRCalculator({ + defaultIp = '10.0.0.0', + defaultCidr = 16, + subnet +}: CIDRCalculatorProps = {}) { + const initialCidr = subnet !== undefined ? Number(subnet) : defaultCidr; + const [ipInput, setIpInput] = useState(defaultIp); + const [cidrInput, setCidrInput] = useState(initialCidr); const [results, setResults] = useState(null); const [error, setError] = useState(''); diff --git a/src/data/cidr-subnets.json b/src/data/cidr-subnets.json new file mode 100644 index 0000000..eb22460 --- /dev/null +++ b/src/data/cidr-subnets.json @@ -0,0 +1,302 @@ +[ + { + "subnet": "3", + "defaultIp": "32.0.0.0", + "usableHosts": 536870910, + "cloudReservedIps": 5, + "subnetMask": "224.0.0.0", + "binaryMask": "11100000.00000000.00000000.00000000", + "commonUseCase": "Ultra-large multi-region aggregation block used for supernet routing and core backbones.", + "terraformSnippet": "# AWS VPC maximum allowed CIDR block size is /16.\n# /3 CIDR blocks are used for supernet route table aggregation.\nresource \"aws_route\" \"supernet_3\" {\n route_table_id = aws_route_table.core.id\n destination_cidr_block = \"32.0.0.0/3\"\n transit_gateway_id = aws_ec2_transit_gateway.main.id\n}" + }, + { + "subnet": "4", + "defaultIp": "16.0.0.0", + "usableHosts": 268435454, + "cloudReservedIps": 5, + "subnetMask": "240.0.0.0", + "binaryMask": "11110000.00000000.00000000.00000000", + "commonUseCase": "Large-scale backbone IP allocation block for major enterprise WAN supernetting.", + "terraformSnippet": "# AWS VPC maximum allowed CIDR block size is /16.\n# /4 CIDR blocks are used for supernet route table aggregation.\nresource \"aws_route\" \"supernet_4\" {\n route_table_id = aws_route_table.core.id\n destination_cidr_block = \"16.0.0.0/4\"\n transit_gateway_id = aws_ec2_transit_gateway.main.id\n}" + }, + { + "subnet": "5", + "defaultIp": "8.0.0.0", + "usableHosts": 134217726, + "cloudReservedIps": 5, + "subnetMask": "248.0.0.0", + "binaryMask": "11111000.00000000.00000000.00000000", + "commonUseCase": "Regional cloud provider backbone allocation supernet.", + "terraformSnippet": "# AWS VPC maximum allowed CIDR block size is /16.\n# /5 CIDR blocks are used for supernet route table aggregation.\nresource \"aws_route\" \"supernet_5\" {\n route_table_id = aws_route_table.core.id\n destination_cidr_block = \"8.0.0.0/5\"\n transit_gateway_id = aws_ec2_transit_gateway.main.id\n}" + }, + { + "subnet": "6", + "defaultIp": "4.0.0.0", + "usableHosts": 67108862, + "cloudReservedIps": 5, + "subnetMask": "252.0.0.0", + "binaryMask": "11111100.00000000.00000000.00000000", + "commonUseCase": "Broad ISP allocation block for regional internet distribution.", + "terraformSnippet": "# AWS VPC maximum allowed CIDR block size is /16.\n# /6 CIDR blocks are used for supernet route table aggregation.\nresource \"aws_route\" \"supernet_6\" {\n route_table_id = aws_route_table.core.id\n destination_cidr_block = \"4.0.0.0/6\"\n transit_gateway_id = aws_ec2_transit_gateway.main.id\n}" + }, + { + "subnet": "7", + "defaultIp": "2.0.0.0", + "usableHosts": 33554430, + "cloudReservedIps": 5, + "subnetMask": "254.0.0.0", + "binaryMask": "11111110.00000000.00000000.00000000", + "commonUseCase": "Aggregate supernet for major global transit networks.", + "terraformSnippet": "# AWS VPC maximum allowed CIDR block size is /16.\n# /7 CIDR blocks are used for supernet route table aggregation.\nresource \"aws_route\" \"supernet_7\" {\n route_table_id = aws_route_table.core.id\n destination_cidr_block = \"2.0.0.0/7\"\n transit_gateway_id = aws_ec2_transit_gateway.main.id\n}" + }, + { + "subnet": "8", + "defaultIp": "10.0.0.0", + "usableHosts": 16777214, + "cloudReservedIps": 5, + "subnetMask": "255.0.0.0", + "binaryMask": "11111111.00000000.00000000.00000000", + "commonUseCase": "Class A private network allocation (10.0.0.0/8) for massive enterprise networks.", + "terraformSnippet": "# AWS VPC CIDR blocks can be up to /16, allocated within private /8 blocks.\nresource \"aws_vpc\" \"vpc_10_0\" {\n cidr_block = \"10.0.0.0/16\"\n enable_dns_hostnames = true\n tags = {\n Name = \"enterprise-vpc-from-10-8\"\n }\n}" + }, + { + "subnet": "9", + "defaultIp": "10.0.0.0", + "usableHosts": 8388606, + "cloudReservedIps": 5, + "subnetMask": "255.128.0.0", + "binaryMask": "11111111.10000000.00000000.00000000", + "commonUseCase": "Half of Class A address space used for global enterprise multi-cloud backbones.", + "terraformSnippet": "# Aggregated enterprise route entry for /9 block.\nresource \"aws_route\" \"supernet_9\" {\n route_table_id = aws_route_table.core.id\n destination_cidr_block = \"10.0.0.0/9\"\n transit_gateway_id = aws_ec2_transit_gateway.main.id\n}" + }, + { + "subnet": "10", + "defaultIp": "100.64.0.0", + "usableHosts": 4194302, + "cloudReservedIps": 5, + "subnetMask": "255.192.0.0", + "binaryMask": "11111111.11000000.00000000.00000000", + "commonUseCase": "Carrier-Grade NAT (CGNAT) / RFC 6598 shared address space.", + "terraformSnippet": "# AWS VPC secondary CIDR block from CGNAT space.\nresource \"aws_vpc_ipv4_cidr_block_association\" \"cgnat\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"100.64.0.0/16\"\n}" + }, + { + "subnet": "11", + "defaultIp": "10.0.0.0", + "usableHosts": 2097150, + "cloudReservedIps": 5, + "subnetMask": "255.224.0.0", + "binaryMask": "11111111.11100000.00000000.00000000", + "commonUseCase": "Large multi-region cloud transit supernet for global hybrid infrastructure.", + "terraformSnippet": "# Transit Gateway CIDR route aggregation block for /11.\nresource \"aws_ec2_transit_gateway_route\" \"route_11\" {\n destination_cidr_block = \"10.0.0.0/11\"\n transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id\n transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.main.id\n}" + }, + { + "subnet": "12", + "defaultIp": "172.16.0.0", + "usableHosts": 1048574, + "cloudReservedIps": 5, + "subnetMask": "255.240.0.0", + "binaryMask": "11111111.11110000.00000000.00000000", + "commonUseCase": "Class B private network allocation (172.16.0.0/12) and Azure Enterprise VNet space.", + "terraformSnippet": "# Azure Virtual Network using the private /12 range.\nresource \"azurerm_virtual_network\" \"vnet\" {\n name = \"enterprise-vnet\"\n address_space = [\"172.16.0.0/12\"]\n location = \"East US\"\n resource_group_name = \"rg-network\"\n}" + }, + { + "subnet": "13", + "defaultIp": "172.16.0.0", + "usableHosts": 524286, + "cloudReservedIps": 5, + "subnetMask": "255.248.0.0", + "binaryMask": "11111111.11111000.00000000.00000000", + "commonUseCase": "Large enterprise WAN aggregation block covering multiple datacenters.", + "terraformSnippet": "# Azure Virtual Network using /13 space.\nresource \"azurerm_virtual_network\" \"vnet_13\" {\n name = \"corp-vnet\"\n address_space = [\"172.16.0.0/13\"]\n location = \"East US\"\n resource_group_name = \"rg-network\"\n}" + }, + { + "subnet": "14", + "defaultIp": "172.16.0.0", + "usableHosts": 262142, + "cloudReservedIps": 5, + "subnetMask": "255.252.0.0", + "binaryMask": "11111111.11111100.00000000.00000000", + "commonUseCase": "Multi-datacenter inter-region transit network for hybrid cloud routing.", + "terraformSnippet": "# Regional WAN route entry for /14 block.\nresource \"aws_route\" \"wan_14\" {\n route_table_id = aws_route_table.core.id\n destination_cidr_block = \"172.16.0.0/14\"\n transit_gateway_id = aws_ec2_transit_gateway.main.id\n}" + }, + { + "subnet": "15", + "defaultIp": "172.16.0.0", + "usableHosts": 131070, + "cloudReservedIps": 5, + "subnetMask": "255.254.0.0", + "binaryMask": "11111111.11111110.00000000.00000000", + "commonUseCase": "Enterprise regional cloud footprint combining multiple VPC networks.", + "terraformSnippet": "# Regional aggregation route for /15 block.\nresource \"aws_route\" \"region_15\" {\n route_table_id = aws_route_table.core.id\n destination_cidr_block = \"172.16.0.0/15\"\n transit_gateway_id = aws_ec2_transit_gateway.main.id\n}" + }, + { + "subnet": "16", + "defaultIp": "10.0.0.0", + "usableHosts": 65534, + "cloudReservedIps": 5, + "subnetMask": "255.255.0.0", + "binaryMask": "11111111.11111111.00000000.00000000", + "commonUseCase": "Maximum allowable size for AWS VPC creation and standard Class B private subnet.", + "terraformSnippet": "resource \"aws_vpc\" \"vpc_16\" {\n cidr_block = \"10.0.0.0/16\"\n enable_dns_hostnames = true\n tags = {\n Name = \"prod-vpc-16\"\n }\n}" + }, + { + "subnet": "17", + "defaultIp": "10.0.0.0", + "usableHosts": 32766, + "cloudReservedIps": 5, + "subnetMask": "255.255.128.0", + "binaryMask": "11111111.11111111.10000000.00000000", + "commonUseCase": "Half VPC address space ideal for splitting multi-region VPC peering setups.", + "terraformSnippet": "resource \"aws_vpc\" \"vpc_17\" {\n cidr_block = \"10.0.0.0/17\"\n enable_dns_hostnames = true\n tags = {\n Name = \"peered-vpc-17\"\n }\n}" + }, + { + "subnet": "18", + "defaultIp": "10.0.0.0", + "usableHosts": 16382, + "cloudReservedIps": 5, + "subnetMask": "255.255.192.0", + "binaryMask": "11111111.11111111.11000000.00000000", + "commonUseCase": "Large cloud subnet block for high-density Kubernetes (EKS/GKE) cluster worker nodes.", + "terraformSnippet": "resource \"aws_subnet\" \"eks_nodes_18\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"10.0.0.0/18\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"eks-high-density-nodes\"\n }\n}" + }, + { + "subnet": "19", + "defaultIp": "10.0.0.0", + "usableHosts": 8190, + "cloudReservedIps": 5, + "subnetMask": "255.255.224.0", + "binaryMask": "11111111.11111111.11100000.00000000", + "commonUseCase": "Regional workload subnet for container platforms requiring high IP density.", + "terraformSnippet": "resource \"aws_subnet\" \"subnet_19\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"10.0.0.0/19\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"container-tier-19\"\n }\n}" + }, + { + "subnet": "20", + "defaultIp": "10.128.0.0", + "usableHosts": 4094, + "cloudReservedIps": 5, + "subnetMask": "255.255.240.0", + "binaryMask": "11111111.11111111.11110000.00000000", + "commonUseCase": "GCP default custom VNet block and standard large availability zone subnet.", + "terraformSnippet": "resource \"google_compute_subnetwork\" \"subnet_20\" {\n name = \"custom-subnet-20\"\n ip_cidr_range = \"10.128.0.0/20\"\n region = \"us-central1\"\n network = google_compute_network.custom.id\n}" + }, + { + "subnet": "21", + "defaultIp": "10.0.0.0", + "usableHosts": 2046, + "cloudReservedIps": 5, + "subnetMask": "255.255.248.0", + "binaryMask": "11111111.11111111.11111000.00000000", + "commonUseCase": "Medium-to-large availability zone subnet supporting up to 2,046 compute instances.", + "terraformSnippet": "resource \"aws_subnet\" \"subnet_21\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"10.0.0.0/21\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"app-tier-21\"\n }\n}" + }, + { + "subnet": "22", + "defaultIp": "10.0.0.0", + "usableHosts": 1022, + "cloudReservedIps": 5, + "subnetMask": "255.255.252.0", + "binaryMask": "11111111.11111111.11111100.00000000", + "commonUseCase": "Standard subnet size for container orchestrators and enterprise application clusters.", + "terraformSnippet": "resource \"aws_subnet\" \"subnet_22\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"10.0.0.0/22\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"cluster-subnet-22\"\n }\n}" + }, + { + "subnet": "23", + "defaultIp": "10.0.0.0", + "usableHosts": 510, + "cloudReservedIps": 5, + "subnetMask": "255.255.254.0", + "binaryMask": "11111111.11111111.11111110.00000000", + "commonUseCase": "Medium cloud subnet providing 510 usable hosts across paired Availability Zones.", + "terraformSnippet": "resource \"aws_subnet\" \"subnet_23\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"10.0.0.0/23\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"az1-subnet-23\"\n }\n}" + }, + { + "subnet": "24", + "defaultIp": "192.168.1.0", + "usableHosts": 254, + "cloudReservedIps": 5, + "subnetMask": "255.255.255.0", + "binaryMask": "11111111.11111111.11111111.00000000", + "commonUseCase": "Standard Class C subnet block widely used in AWS VPC availability zones and LANs.", + "terraformSnippet": "resource \"aws_subnet\" \"subnet_24\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"192.168.1.0/24\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"prod-subnet-24\"\n }\n}" + }, + { + "subnet": "25", + "defaultIp": "192.168.1.0", + "usableHosts": 126, + "cloudReservedIps": 5, + "subnetMask": "255.255.255.128", + "binaryMask": "11111111.11111111.11111111.10000000", + "commonUseCase": "Half Class C subnet ideal for dedicated public or private tier isolation.", + "terraformSnippet": "resource \"aws_subnet\" \"subnet_25\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"192.168.1.0/25\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"app-tier-25\"\n }\n}" + }, + { + "subnet": "26", + "defaultIp": "192.168.1.0", + "usableHosts": 62, + "cloudReservedIps": 5, + "subnetMask": "255.255.255.192", + "binaryMask": "11111111.11111111.11111111.11000000", + "commonUseCase": "Quarter Class C subnet standard for API gateway tiers or database subnets.", + "terraformSnippet": "resource \"aws_subnet\" \"subnet_26\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"192.168.1.0/26\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"db-tier-26\"\n }\n}" + }, + { + "subnet": "27", + "defaultIp": "192.168.1.0", + "usableHosts": 30, + "cloudReservedIps": 5, + "subnetMask": "255.255.255.224", + "binaryMask": "11111111.11111111.11111111.11100000", + "commonUseCase": "Small tier subnet common for load balancer target groups and NAT gateways.", + "terraformSnippet": "resource \"aws_subnet\" \"subnet_27\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"192.168.1.0/27\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"alb-tier-27\"\n }\n}" + }, + { + "subnet": "28", + "defaultIp": "192.168.1.0", + "usableHosts": 14, + "cloudReservedIps": 5, + "subnetMask": "255.255.255.240", + "binaryMask": "11111111.11111111.11111111.11110000", + "commonUseCase": "AWS VPC minimum allowable subnet size providing 14 usable IP addresses (9 in AWS).", + "terraformSnippet": "resource \"aws_subnet\" \"subnet_28\" {\n vpc_id = aws_vpc.main.id\n cidr_block = \"192.168.1.0/28\"\n availability_zone = \"us-east-1a\"\n tags = {\n Name = \"aws-min-subnet-28\"\n }\n}" + }, + { + "subnet": "29", + "defaultIp": "192.168.1.0", + "usableHosts": 6, + "cloudReservedIps": 5, + "subnetMask": "255.255.255.248", + "binaryMask": "11111111.11111111.11111111.11111000", + "commonUseCase": "Micro-subnet for small firewall clusters, hardware appliances, or transit nodes.", + "terraformSnippet": "# Note: AWS VPC subnets require a minimum size of /28.\n# /29 subnets are defined via Security Group rule CIDRs or custom router ACLs.\nresource \"aws_vpc_security_group_ingress_rule\" \"ingress_29\" {\n security_group_id = aws_security_group.app.id\n cidr_ipv4 = \"192.168.1.0/29\"\n from_port = 443\n ip_protocol = \"tcp\"\n to_port = 443\n}" + }, + { + "subnet": "30", + "defaultIp": "192.168.1.0", + "usableHosts": 2, + "cloudReservedIps": 4, + "subnetMask": "255.255.255.252", + "binaryMask": "11111111.11111111.11111111.11111100", + "commonUseCase": "Point-to-point router links and private interconnect virtual interfaces.", + "terraformSnippet": "# Note: AWS VPC subnets require a minimum size of /28.\n# /30 subnets represent point-to-point interconnects & Transit Gateway routes.\nresource \"aws_ec2_transit_gateway_route\" \"p2p_30\" {\n destination_cidr_block = \"192.168.1.0/30\"\n transit_gateway_route_table_id = aws_ec2_transit_gateway_route_table.main.id\n transit_gateway_attachment_id = aws_ec2_transit_gateway_connect_peer.peer.id\n}" + }, + { + "subnet": "31", + "defaultIp": "192.168.1.0", + "usableHosts": 2, + "cloudReservedIps": 0, + "subnetMask": "255.255.255.254", + "binaryMask": "11111111.11111111.11111111.11111110", + "commonUseCase": "RFC 3021 point-to-point links using zero broadcast addresses for router links.", + "terraformSnippet": "# Note: AWS VPC subnets require a minimum size of /28.\n# /31 subnets (RFC 3021) are used for point-to-point router links & DirectConnect BGP.\nresource \"aws_route\" \"p2p_31\" {\n route_table_id = aws_route_table.core.id\n destination_cidr_block = \"192.168.1.0/31\"\n transit_gateway_id = aws_ec2_transit_gateway.main.id\n}" + }, + { + "subnet": "32", + "defaultIp": "192.168.1.1", + "usableHosts": 1, + "cloudReservedIps": 0, + "subnetMask": "255.255.255.255", + "binaryMask": "11111111.11111111.11111111.11111111", + "commonUseCase": "Single host loopback address, host route, or security group rule target IP.", + "terraformSnippet": "# Note: AWS VPC subnets require a minimum size of /28.\n# /32 represents a single host route or Security Group ingress rule.\nresource \"aws_vpc_security_group_ingress_rule\" \"host_32\" {\n security_group_id = aws_security_group.app.id\n cidr_ipv4 = \"192.168.1.1/32\"\n from_port = 22\n ip_protocol = \"tcp\"\n to_port = 22\n}" + } +] diff --git a/src/pages/cidr-subnet-calculator.astro b/src/pages/cidr-subnet-calculator.astro index 2545d93..642e91d 100644 --- a/src/pages/cidr-subnet-calculator.astro +++ b/src/pages/cidr-subnet-calculator.astro @@ -2,6 +2,7 @@ import Layout from '../layouts/Layout.astro'; import CIDRCalculator from '../components/tools/CIDRCalculator'; import RelatedTools from '../components/shared/RelatedTools.astro'; +import subnetsData from '../data/cidr-subnets.json'; const toolFaqs = [ { @@ -207,13 +208,13 @@ Broadcast: 172.16.15.255 - {/* 5. Subnet Cheat Sheet Reference Module */} + {/* 5. Subnet Cheat Sheet Reference Module with Internal Links */}

Core Subnet Cheat Sheet Matrix

A quick-reference mask structure guide for mapping the most common local network configurations across typical DevOps and cloud environments:

-
+
@@ -221,19 +222,55 @@ Broadcast: 172.16.15.255 + - - - - - + {subnetsData.filter(s => ['8', '12', '16', '20', '24', '25', '26', '27', '28', '30', '32'].includes(s.subnet)).map((item) => ( + + + + + + + + ))}
Subnet Mask Total Host Count Usable CapacityDetails
/24255.255.255.0256254
/25255.255.255.128128126
/26255.255.255.1926462
/27255.255.255.2243230
/30255.255.255.25242
+ + /{item.subnet} Subnet + + {item.subnetMask}{(item.usableHosts + (parseInt(item.subnet, 10) >= 31 ? 0 : 2)).toLocaleString()}{item.usableHosts.toLocaleString()} + + View /{item.subnet} Specs → + +
+ {/* 5b. Complete CIDR Subnet Directory (Internal pSEO Link Hub) */} +
+

Browse All CIDR Subnet Specifications & Calculators

+

+ Select any IPv4 CIDR prefix below to view pre-computed routing specs, binary masks, cloud host limits, and copyable Terraform configuration blocks: +

+ +
+ {/* 6. SRE Technical Context Stack Section */}

Maintaining Security inside Site Reliability Engineering

diff --git a/src/pages/cidr-subnet-calculator/[subnet]-subnet.astro b/src/pages/cidr-subnet-calculator/[subnet]-subnet.astro new file mode 100644 index 0000000..fc54e5a --- /dev/null +++ b/src/pages/cidr-subnet-calculator/[subnet]-subnet.astro @@ -0,0 +1,322 @@ +--- +import Layout from '../../layouts/Layout.astro'; +import CIDRCalculator from '../../components/tools/CIDRCalculator'; +import RelatedTools from '../../components/shared/RelatedTools.astro'; +import subnetsData from '../../data/cidr-subnets.json'; + +export async function getStaticPaths() { + return subnetsData.map((item, index) => { + // In CIDR notation: + // Smaller slash number = Larger network (e.g., /23 provides double the hosts of /24) + // Larger slash number = Smaller network (e.g., /25 provides half the hosts of /24) + const prevSubnet = index > 0 ? subnetsData[index - 1] : null; // Next larger network + const nextSubnet = index < subnetsData.length - 1 ? subnetsData[index + 1] : null; // Next smaller network + return { + params: { subnet: item.subnet }, + props: { data: item, prevSubnet, nextSubnet }, + }; + }); +} + +const { data, prevSubnet, nextSubnet } = Astro.props; +const subnetNum = parseInt(data.subnet, 10); +const pageTitle = `Usable Host Range for /${data.subnet} Subnet | ConfigDev Offline Calculator`; +const pageDescription = `/${data.subnet} subnet: ${data.usableHosts.toLocaleString()} usable hosts, netmask ${data.subnetMask}. Binary mask, cloud reserved IPs & Terraform snippet. Free client-side IPv4 tool.`; + +const jsonLd = { + "@context": "https://schema.org", + "@graph": [ + { + "@type": "TechArticle", + "@id": `https://configdev.com/cidr-subnet-calculator/${data.subnet}-subnet#article`, + "headline": `CIDR /${data.subnet} Subnet Technical Specifications & Host Calculations`, + "description": `Detailed IPv4 subnet parameters for /${data.subnet} networks. Netmask: ${data.subnetMask}. Usable host capacity: ${data.usableHosts.toLocaleString()} IPs. Common use case: ${data.commonUseCase}`, + "inLanguage": "en", + "author": { + "@type": "Organization", + "name": "ConfigDev", + "url": "https://configdev.com" + }, + "publisher": { + "@type": "Organization", + "name": "ConfigDev", + "url": "https://configdev.com", + "logo": { + "@type": "ImageObject", + "url": "https://configdev.com/icon.png" + } + } + }, + { + "@type": "WebApplication", + "@id": `https://configdev.com/cidr-subnet-calculator/${data.subnet}-subnet#app`, + "url": `https://configdev.com/cidr-subnet-calculator/${data.subnet}-subnet`, + "name": `/${data.subnet} CIDR Subnet Calculator`, + "applicationCategory": "DeveloperApplication", + "operatingSystem": "All", + "browserRequirements": "Requires JavaScript. Runs 100% client-side inside local browser memory sandbox." + }, + { + "@type": "BreadcrumbList", + "itemListElement": [ + { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://configdev.com/" }, + { "@type": "ListItem", "position": 2, "name": "CIDR Subnet Calculator", "item": "https://configdev.com/cidr-subnet-calculator" }, + { "@type": "ListItem", "position": 3, "name": `/${data.subnet} Subnet`, "item": `https://configdev.com/cidr-subnet-calculator/${data.subnet}-subnet` } + ] + } + ] +}; +--- + + + + +
+ {/* Breadcrumb Navigation */} + + + {/* Header Section Layout */} +
+
+
+
+ CIDR Prefix: /{data.subnet} +
+

+ Usable Host Range for /{data.subnet} Subnet +

+

+ {data.commonUseCase} Pre-calculated routing boundaries, binary mapping mask, cloud provider allocation metrics, and copy-ready Terraform snippets. +

+
+ +
+ + 100% Free & Secure Client-Side Sandbox +
+
+
+ + {/* Pre-Loaded Instant Calculator Workspace */} +
+
+

+ Interactive /{data.subnet} Subnet Workspace +

+ + Pre-loaded Seed: {data.defaultIp}/{data.subnet} + +
+ +
+ + {/* Technical Specifications Grid & Data Table */} +
+
+

+ Pre-Computed /{data.subnet} Subnet Technical Specifications +

+ Verified 32-bit Bitwise Calculation Matrix +
+ +
+
+
+ + Subnet Mask (Dotted Decimal) + + + {data.subnetMask} + +
+ +
+ + Usable Host Capacity + + + {data.usableHosts.toLocaleString()} IPs + +
+ +
+ + Cloud Reserved IPs (AWS) + + + {data.cloudReservedIps} IPs + +
+ +
+ + Default Range Seed + + + {data.defaultIp}/{data.subnet} + +
+
+ + {/* Deep Specs Table */} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Binary Mask Blueprint{data.binaryMask}
CIDR Notation/{data.subnet}
Netmask Address{data.subnetMask}
Total Host Addresses{(data.usableHosts + (subnetNum >= 31 ? 0 : 2)).toLocaleString()}
Usable Hosts (Standard IPv4){data.usableHosts.toLocaleString()} usable IPs
Cloud Net Capacity (AWS / GCP) + {Math.max(0, data.usableHosts + (subnetNum >= 31 ? 0 : 2) - data.cloudReservedIps).toLocaleString()} usable IPs + + (AWS reserves 5 addresses: Network, VPC Router, DNS, Reserved, Broadcast) + +
Primary Architectural Use Case{data.commonUseCase}
+
+ + {/* Copyable IaC Terraform Block */} +
+
+

+ Terraform IaC Configuration Block (/{data.subnet}) +

+ Copy-ready infrastructure code +
+
+
{data.terraformSnippet}
+
+
+
+
+ + {/* Internal Linking & Related Subnets Matrix */} +
+ + + + + {/* Popular CIDR Quick Shortcuts Grid */} +
+

+ Popular Cloud & DevOps CIDR Prefixes +

+
+ {['8', '16', '20', '24', '25', '26', '27', '28', '30', '32'].map((item) => ( + + /{item} Subnet + + ))} +
+
+
+ + {/* Related Tools Navigation */} + +
+