first commit
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
# Optional production-style path
|
||||
|
||||
This directory provisions one encrypted Ubuntu EC2 host with a deliberately
|
||||
small network surface. It is a scaffold for the documented cloud path; the
|
||||
local k3d path remains the primary, cost-free portfolio demo.
|
||||
|
||||
The AWS account, region, AMI, SSH key pair, and administrator CIDR are inputs,
|
||||
not repository values. Do not commit a real `terraform.tfvars` file or private
|
||||
keys. The security group intentionally exposes SSH and the Kubernetes API only
|
||||
to `admin_cidr`; add any public application ports explicitly when needed.
|
||||
|
||||
Example workflow:
|
||||
|
||||
```bash
|
||||
cp terraform.tfvars.example terraform.tfvars
|
||||
# Edit every replace-* value and set admin_cidr to your current IP /32.
|
||||
terraform init
|
||||
terraform validate
|
||||
terraform plan
|
||||
terraform apply
|
||||
terraform output -raw public_ip
|
||||
```
|
||||
|
||||
Then run `ansible/bootstrap-k3s.yml` against the output IP. `terraform destroy`
|
||||
removes the lab resources when finished. This path is not required for the
|
||||
portfolio demo and is not invoked by CI.
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
data "aws_availability_zones" "available" {
|
||||
state = "available"
|
||||
}
|
||||
|
||||
locals {
|
||||
availability_zone = coalesce(var.availability_zone, data.aws_availability_zones.available.names[0])
|
||||
}
|
||||
|
||||
resource "aws_vpc" "cluster" {
|
||||
cidr_block = "10.42.0.0/16"
|
||||
enable_dns_hostnames = true
|
||||
enable_dns_support = true
|
||||
|
||||
tags = { Name = "k8s-security-baseline" }
|
||||
}
|
||||
|
||||
resource "aws_subnet" "cluster" {
|
||||
vpc_id = aws_vpc.cluster.id
|
||||
cidr_block = "10.42.1.0/24"
|
||||
availability_zone = local.availability_zone
|
||||
|
||||
tags = { Name = "k8s-security-baseline" }
|
||||
}
|
||||
|
||||
resource "aws_internet_gateway" "cluster" {
|
||||
vpc_id = aws_vpc.cluster.id
|
||||
}
|
||||
|
||||
resource "aws_route_table" "cluster" {
|
||||
vpc_id = aws_vpc.cluster.id
|
||||
|
||||
route {
|
||||
cidr_block = "0.0.0.0/0"
|
||||
gateway_id = aws_internet_gateway.cluster.id
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "cluster" {
|
||||
subnet_id = aws_subnet.cluster.id
|
||||
route_table_id = aws_route_table.cluster.id
|
||||
}
|
||||
|
||||
resource "aws_security_group" "cluster" {
|
||||
name = "k8s-security-baseline"
|
||||
description = "Minimal access for the optional single-node K3s lab host"
|
||||
vpc_id = aws_vpc.cluster.id
|
||||
|
||||
ingress {
|
||||
description = "SSH from the administrator CIDR"
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = [var.admin_cidr]
|
||||
}
|
||||
|
||||
ingress {
|
||||
description = "Kubernetes API from the administrator CIDR"
|
||||
from_port = 6443
|
||||
to_port = 6443
|
||||
protocol = "tcp"
|
||||
cidr_blocks = [var.admin_cidr]
|
||||
}
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_instance" "k3s" {
|
||||
ami = var.ami_id
|
||||
instance_type = var.instance_type
|
||||
subnet_id = aws_subnet.cluster.id
|
||||
vpc_security_group_ids = [aws_security_group.cluster.id]
|
||||
key_name = var.ssh_key_name
|
||||
associate_public_ip_address = true
|
||||
|
||||
root_block_device {
|
||||
volume_size = 30
|
||||
volume_type = "gp3"
|
||||
encrypted = true
|
||||
}
|
||||
|
||||
tags = { Name = "k8s-security-baseline" }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
output "public_ip" {
|
||||
description = "Public IP to place in the Ansible inventory."
|
||||
value = aws_instance.k3s.public_ip
|
||||
}
|
||||
|
||||
output "ssh_command" {
|
||||
description = "SSH command for initial connectivity testing."
|
||||
value = "ssh ubuntu@${aws_instance.k3s.public_ip}"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
aws_region = "us-east-1"
|
||||
availability_zone = null
|
||||
instance_type = "t3.medium"
|
||||
ssh_key_name = "replace-with-existing-key-pair"
|
||||
admin_cidr = "203.0.113.10/32"
|
||||
ami_id = "replace-with-ubuntu-22.04-ami-for-your-region"
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
variable "aws_region" {
|
||||
description = "AWS region for the optional production-style K3s host."
|
||||
type = string
|
||||
default = "us-east-1"
|
||||
}
|
||||
|
||||
variable "availability_zone" {
|
||||
description = "Availability zone for the subnet. Leave null to use the first AZ."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "instance_type" {
|
||||
description = "EC2 instance type for the lab node."
|
||||
type = string
|
||||
default = "t3.medium"
|
||||
}
|
||||
|
||||
variable "ssh_key_name" {
|
||||
description = "Existing EC2 key pair name used for Ansible bootstrap."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "admin_cidr" {
|
||||
description = "CIDR allowed to SSH to the node; restrict this to your admin IP."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "ami_id" {
|
||||
description = "Ubuntu 22.04 LTS AMI ID for the selected region."
|
||||
type = string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
terraform {
|
||||
required_version = ">= 1.6.0"
|
||||
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = var.aws_region
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user