feat: distribution package v1.0 — OCIR-based deployment without source code

- distribution/: public release package (docker-compose + terraform VM + README v1.0)
- docker-compose.yml pulls pre-built images from OCIR (no build, no source code)
- terraform/: VM stack (ARM Free Tier, LB+WAF+SSL, conditional DNS/Let's Encrypt)
- Removed terraform-oke/ and k8s/ from git (private, .gitignore)
This commit is contained in:
nogueiraguh
2026-04-02 13:46:28 -03:00
parent 5efde6fcf4
commit abf248d714
27 changed files with 1052 additions and 945 deletions

View File

@@ -1,11 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: oci-cis-agent-config
namespace: oci-cis-agent
data:
JWT_EXPIRY_HOURS: "12"
TZ: "America/Sao_Paulo"
DATA_DIR: "/data"
CORS_ORIGINS: "https://LOAD_BALANCER_IP"
OCI_CLI_SUPPRESS_FILE_PERMISSIONS_WARNING: "True"

View File

@@ -1,111 +0,0 @@
##
## Backend — FastAPI (port 8000)
##
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: oci-cis-agent
labels:
app: oci-cis-agent-backend
spec:
replicas: 1
selector:
matchLabels:
app: oci-cis-agent-backend
template:
metadata:
labels:
app: oci-cis-agent-backend
spec:
imagePullSecrets:
- name: ocir-credentials
containers:
- name: backend
image: OCIR_REGION.ocir.io/OCIR_NAMESPACE/oci-cis-agent-backend:latest
ports:
- containerPort: 8000
envFrom:
- configMapRef:
name: oci-cis-agent-config
env:
- name: APP_SECRET
valueFrom:
secretKeyRef:
name: app-secret
key: APP_SECRET
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
memory: "2Gi"
cpu: "500m"
limits:
memory: "4Gi"
cpu: "2000m"
readinessProbe:
httpGet:
path: /api/health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /api/health
port: 8000
initialDelaySeconds: 60
periodSeconds: 30
volumes:
- name: data
persistentVolumeClaim:
claimName: oci-cis-agent-data
---
##
## Frontend — nginx (port 80)
##
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: oci-cis-agent
labels:
app: oci-cis-agent-frontend
spec:
replicas: 1
selector:
matchLabels:
app: oci-cis-agent-frontend
template:
metadata:
labels:
app: oci-cis-agent-frontend
spec:
imagePullSecrets:
- name: ocir-credentials
containers:
- name: frontend
image: OCIR_REGION.ocir.io/OCIR_NAMESPACE/oci-cis-agent-frontend:latest
ports:
- containerPort: 80
env:
- name: TZ
valueFrom:
configMapKeyRef:
name: oci-cis-agent-config
key: TZ
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10

View File

@@ -1,6 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: oci-cis-agent
labels:
app.kubernetes.io/part-of: oci-cis-agent

View File

@@ -1,12 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: oci-cis-agent-data
namespace: oci-cis-agent
spec:
accessModes:
- ReadWriteOnce
storageClassName: oci-bv
resources:
requests:
storage: 50Gi

View File

@@ -1,35 +0,0 @@
##
## Fill in the placeholder values before applying.
##
## APP_SECRET: generate with python -c "import secrets; print(secrets.token_hex(64))"
## then base64-encode it: echo -n '<value>' | base64
##
## OCIR dockerconfigjson:
## kubectl create secret docker-registry ocir-credentials \
## --namespace oci-cis-agent \
## --docker-server=OCIR_REGION.ocir.io \
## --docker-username='OCIR_NAMESPACE/USERNAME' \
## --docker-password='AUTH_TOKEN' \
## --dry-run=client -o yaml
## Copy the .data[.dockerconfigjson] value below.
##
apiVersion: v1
kind: Secret
metadata:
name: app-secret
namespace: oci-cis-agent
type: Opaque
data:
APP_SECRET: "<BASE64_ENCODED_APP_SECRET>"
---
apiVersion: v1
kind: Secret
metadata:
name: ocir-credentials
namespace: oci-cis-agent
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: "<BASE64_ENCODED_DOCKER_CONFIG_JSON>"

View File

@@ -1,42 +0,0 @@
##
## Backend service — ClusterIP (internal only)
## Named "backend" so the frontend nginx proxy_pass http://backend:8000/api/ resolves via K8s DNS.
##
apiVersion: v1
kind: Service
metadata:
name: backend
namespace: oci-cis-agent
labels:
app: oci-cis-agent-backend
spec:
type: ClusterIP
selector:
app: oci-cis-agent-backend
ports:
- port: 8000
targetPort: 8000
protocol: TCP
---
##
## Frontend service — NodePort
## nodePort 30080 matches the OCI Load Balancer backend set.
##
apiVersion: v1
kind: Service
metadata:
name: frontend
namespace: oci-cis-agent
labels:
app: oci-cis-agent-frontend
spec:
type: NodePort
selector:
app: oci-cis-agent-frontend
ports:
- port: 80
targetPort: 80
nodePort: 30080
protocol: TCP

View File

@@ -1,29 +0,0 @@
# -----------------------------------------------------------------------------
# OCI CIS Agent — OKE Deployment Stack
# DNS: Conditional Zone + A Record (only when domain_name is set)
# -----------------------------------------------------------------------------
resource "oci_dns_zone" "main" {
count = var.domain_name != "" ? 1 : 0
compartment_id = var.compartment_ocid
name = var.domain_name
zone_type = "PRIMARY"
freeform_tags = var.freeform_tags
}
resource "oci_dns_rrset" "app_a_record" {
count = var.domain_name != "" ? 1 : 0
zone_name_or_id = oci_dns_zone.main[0].id
domain = var.domain_name
rtype = "A"
compartment_id = var.compartment_ocid
items {
domain = var.domain_name
rdata = oci_load_balancer_load_balancer.main.ip_address_details[0].ip_address
rtype = "A"
ttl = 300
}
}

View File

@@ -1,157 +0,0 @@
# -----------------------------------------------------------------------------
# OCI CIS Agent — OKE Deployment Stack
# Load Balancer: Self-Signed TLS, HTTPS/HTTP Listeners, Backend Set
# -----------------------------------------------------------------------------
# --- Self-Signed TLS Certificate ---
resource "tls_private_key" "lb" {
algorithm = "RSA"
rsa_bits = 2048
}
resource "tls_self_signed_cert" "lb" {
private_key_pem = tls_private_key.lb.private_key_pem
subject {
common_name = var.domain_name != "" ? var.domain_name : "oci-cis-agent.local"
organization = "OCI CIS Agent"
}
validity_period_hours = 8760 # 1 year
is_ca_certificate = false
allowed_uses = [
"key_encipherment",
"digital_signature",
"server_auth",
]
}
# --- Load Balancer ---
resource "oci_load_balancer_load_balancer" "main" {
compartment_id = var.compartment_ocid
display_name = "cisagent-oke-lb"
shape = "flexible"
shape_details {
minimum_bandwidth_in_mbps = var.lb_min_bandwidth_mbps
maximum_bandwidth_in_mbps = var.lb_max_bandwidth_mbps
}
subnet_ids = [oci_core_subnet.public.id]
is_private = false
freeform_tags = var.freeform_tags
}
# --- Certificate ---
resource "oci_load_balancer_certificate" "main" {
load_balancer_id = oci_load_balancer_load_balancer.main.id
certificate_name = "cisagent-self-signed"
public_certificate = tls_self_signed_cert.lb.cert_pem
private_key = tls_private_key.lb.private_key_pem
lifecycle {
create_before_destroy = true
}
}
# --- Backend Set ---
# Backends point to worker node IPs on the fixed NodePort.
# The K8s Service must use spec.type=NodePort with nodePort=30080.
resource "oci_load_balancer_backend_set" "app" {
load_balancer_id = oci_load_balancer_load_balancer.main.id
name = "cisagent-backend-set"
policy = "ROUND_ROBIN"
health_checker {
protocol = "HTTP"
port = var.node_port
url_path = "/api/health"
return_code = 200
interval_ms = 10000
timeout_in_millis = 5000
retries = 3
}
}
# --- Backends (one per worker node) ---
# Uses node private IPs from the node pool data source.
resource "oci_load_balancer_backend" "nodes" {
for_each = {
for idx, node in data.oci_containerengine_node_pool.app.nodes :
idx => node
if node.state == "ACTIVE"
}
load_balancer_id = oci_load_balancer_load_balancer.main.id
backendset_name = oci_load_balancer_backend_set.app.name
ip_address = each.value.private_ip
port = var.node_port
weight = 1
}
# --- HTTPS Listener (443) ---
resource "oci_load_balancer_listener" "https" {
load_balancer_id = oci_load_balancer_load_balancer.main.id
name = "cisagent-https"
default_backend_set_name = oci_load_balancer_backend_set.app.name
port = 443
protocol = "HTTP"
ssl_configuration {
certificate_name = oci_load_balancer_certificate.main.certificate_name
verify_peer_certificate = false
protocols = ["TLSv1.2", "TLSv1.3"]
}
}
# --- HTTP Listener (80) with redirect to HTTPS ---
resource "oci_load_balancer_listener" "http_redirect" {
load_balancer_id = oci_load_balancer_load_balancer.main.id
name = "cisagent-http-redirect"
default_backend_set_name = oci_load_balancer_backend_set.app.name
port = 80
protocol = "HTTP"
rule_set_names = [oci_load_balancer_rule_set.http_redirect.name]
connection_configuration {
idle_timeout_in_seconds = 60
}
}
# --- Rule Set: HTTP to HTTPS Redirect ---
resource "oci_load_balancer_rule_set" "http_redirect" {
load_balancer_id = oci_load_balancer_load_balancer.main.id
name = "http-to-https-redirect"
items {
action = "REDIRECT"
description = "Redirect HTTP to HTTPS"
conditions {
attribute_name = "PATH"
attribute_value = "/"
operator = "FORCE_LONGEST_PREFIX_MATCH"
}
redirect_uri {
protocol = "HTTPS"
port = 443
host = "{host}"
path = "/{path}"
query = "?{query}"
}
response_code = 301
}
}

View File

@@ -1,287 +0,0 @@
# -----------------------------------------------------------------------------
# OCI CIS Agent — OKE Deployment Stack
# Networking: VCN, Gateways, Subnets, Route Tables, Security Lists
# -----------------------------------------------------------------------------
# --- VCN ---
resource "oci_core_vcn" "main" {
compartment_id = var.compartment_ocid
cidr_blocks = [var.vcn_cidr]
display_name = "cisagent-oke-vcn"
dns_label = "cisagentoke"
freeform_tags = var.freeform_tags
}
# --- Gateways ---
resource "oci_core_internet_gateway" "main" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
display_name = "cisagent-oke-igw"
enabled = true
freeform_tags = var.freeform_tags
}
resource "oci_core_nat_gateway" "main" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
display_name = "cisagent-oke-natgw"
freeform_tags = var.freeform_tags
}
data "oci_core_services" "all" {
filter {
name = "name"
values = ["All .* Services In Oracle Services Network"]
regex = true
}
}
resource "oci_core_service_gateway" "main" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
display_name = "cisagent-oke-svcgw"
services {
service_id = data.oci_core_services.all.services[0].id
}
freeform_tags = var.freeform_tags
}
# --- Route Tables ---
resource "oci_core_route_table" "public" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
display_name = "cisagent-oke-rt-public"
route_rules {
network_entity_id = oci_core_internet_gateway.main.id
destination = "0.0.0.0/0"
destination_type = "CIDR_BLOCK"
}
freeform_tags = var.freeform_tags
}
resource "oci_core_route_table" "private" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
display_name = "cisagent-oke-rt-private"
route_rules {
network_entity_id = oci_core_nat_gateway.main.id
destination = "0.0.0.0/0"
destination_type = "CIDR_BLOCK"
}
route_rules {
network_entity_id = oci_core_service_gateway.main.id
destination = data.oci_core_services.all.services[0].cidr_block
destination_type = "SERVICE_CIDR_BLOCK"
}
freeform_tags = var.freeform_tags
}
# --- Security Lists ---
# Public subnet: LB ingress on 80/443, egress all
resource "oci_core_security_list" "public" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
display_name = "cisagent-oke-sl-public"
ingress_security_rules {
protocol = "6" # TCP
source = "0.0.0.0/0"
stateless = false
tcp_options {
min = 80
max = 80
}
}
ingress_security_rules {
protocol = "6"
source = "0.0.0.0/0"
stateless = false
tcp_options {
min = 443
max = 443
}
}
egress_security_rules {
protocol = "all"
destination = "0.0.0.0/0"
stateless = false
}
freeform_tags = var.freeform_tags
}
# Nodes subnet: pod-to-pod, kubelet, NodePort, SSH
resource "oci_core_security_list" "nodes" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
display_name = "cisagent-oke-sl-nodes"
# Pod-to-pod communication (all traffic within nodes subnet)
ingress_security_rules {
protocol = "all"
source = var.nodes_subnet_cidr
stateless = false
}
# Kubelet API from API endpoint subnet
ingress_security_rules {
protocol = "6"
source = var.api_subnet_cidr
stateless = false
tcp_options {
min = 10250
max = 10250
}
}
# NodePort range from public subnet (LB health checks + traffic)
ingress_security_rules {
protocol = "6"
source = var.public_subnet_cidr
stateless = false
tcp_options {
min = 30000
max = 32767
}
}
# SSH from VCN (for debugging)
ingress_security_rules {
protocol = "6"
source = var.vcn_cidr
stateless = false
tcp_options {
min = 22
max = 22
}
}
# ICMP Path Discovery
ingress_security_rules {
protocol = "1" # ICMP
source = var.vcn_cidr
stateless = false
icmp_options {
type = 3
code = 4
}
}
egress_security_rules {
protocol = "all"
destination = "0.0.0.0/0"
stateless = false
}
freeform_tags = var.freeform_tags
}
# API endpoint subnet: Kubernetes API access
resource "oci_core_security_list" "api_endpoint" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
display_name = "cisagent-oke-sl-api"
# Kubernetes API from worker nodes
ingress_security_rules {
protocol = "6"
source = var.nodes_subnet_cidr
stateless = false
tcp_options {
min = 6443
max = 6443
}
}
# Kubernetes API from VCN (kubectl access via bastion / VPN)
ingress_security_rules {
protocol = "6"
source = var.vcn_cidr
stateless = false
tcp_options {
min = 6443
max = 6443
}
}
# Kubernetes API from worker nodes (12250 for OKE control plane)
ingress_security_rules {
protocol = "6"
source = var.nodes_subnet_cidr
stateless = false
tcp_options {
min = 12250
max = 12250
}
}
# ICMP Path Discovery
ingress_security_rules {
protocol = "1"
source = var.vcn_cidr
stateless = false
icmp_options {
type = 3
code = 4
}
}
egress_security_rules {
protocol = "all"
destination = "0.0.0.0/0"
stateless = false
}
freeform_tags = var.freeform_tags
}
# --- Subnets ---
# Public subnet: Load Balancer
resource "oci_core_subnet" "public" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
cidr_block = var.public_subnet_cidr
display_name = "cisagent-oke-subnet-public"
dns_label = "publb"
prohibit_public_ip_on_vnic = false
route_table_id = oci_core_route_table.public.id
security_list_ids = [oci_core_security_list.public.id]
freeform_tags = var.freeform_tags
}
# Private subnet: OKE worker nodes
resource "oci_core_subnet" "nodes" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
cidr_block = var.nodes_subnet_cidr
display_name = "cisagent-oke-subnet-nodes"
dns_label = "nodes"
prohibit_public_ip_on_vnic = true
route_table_id = oci_core_route_table.private.id
security_list_ids = [oci_core_security_list.nodes.id]
freeform_tags = var.freeform_tags
}
# Private subnet: OKE API endpoint
resource "oci_core_subnet" "api_endpoint" {
compartment_id = var.compartment_ocid
vcn_id = oci_core_vcn.main.id
cidr_block = var.api_subnet_cidr
display_name = "cisagent-oke-subnet-api"
dns_label = "api"
prohibit_public_ip_on_vnic = true
route_table_id = oci_core_route_table.private.id
security_list_ids = [oci_core_security_list.api_endpoint.id]
freeform_tags = var.freeform_tags
}

View File

@@ -1,116 +0,0 @@
# -----------------------------------------------------------------------------
# OCI CIS Agent — OKE Deployment Stack
# OKE Cluster + Node Pool
# -----------------------------------------------------------------------------
# --- Data Sources ---
data "oci_identity_availability_domains" "ads" {
compartment_id = var.tenancy_ocid
}
# Latest Oracle Linux 8 image compatible with VM.Standard3.Flex
data "oci_core_images" "oracle_linux" {
compartment_id = var.compartment_ocid
operating_system = "Oracle Linux"
operating_system_version = "8"
shape = var.node_shape
sort_by = "TIMECREATED"
sort_order = "DESC"
filter {
name = "display_name"
values = ["^Oracle-Linux-8\\.\\d+-\\d{4}\\.\\d{2}\\.\\d{2}-\\d+$"]
regex = true
}
}
# --- OKE Cluster ---
resource "oci_containerengine_cluster" "main" {
compartment_id = var.compartment_ocid
kubernetes_version = var.kubernetes_version
name = var.cluster_name
vcn_id = oci_core_vcn.main.id
type = "ENHANCED_CLUSTER"
cluster_pod_network_options {
cni_type = "FLANNEL_OVERLAY"
}
endpoint_config {
is_public_ip_enabled = false
subnet_id = oci_core_subnet.api_endpoint.id
}
options {
service_lb_subnet_ids = [oci_core_subnet.public.id]
kubernetes_network_config {
pods_cidr = "10.244.0.0/16"
services_cidr = "10.96.0.0/16"
}
persistent_volume_config {
freeform_tags = var.freeform_tags
}
service_lb_config {
freeform_tags = var.freeform_tags
}
}
freeform_tags = var.freeform_tags
}
# --- Node Pool ---
resource "oci_containerengine_node_pool" "app" {
compartment_id = var.compartment_ocid
cluster_id = oci_containerengine_cluster.main.id
kubernetes_version = var.kubernetes_version
name = "${var.cluster_name}-nodepool"
node_shape = var.node_shape
node_shape_config {
ocpus = var.node_ocpus
memory_in_gbs = var.node_memory_gb
}
node_source_details {
source_type = "IMAGE"
image_id = data.oci_core_images.oracle_linux.images[0].id
boot_volume_size_in_gbs = var.node_boot_volume_gb
}
node_config {
size = var.node_count
# Place nodes across all available ADs for HA
dynamic "placement_configs" {
for_each = data.oci_identity_availability_domains.ads.availability_domains
content {
availability_domain = placement_configs.value.name
subnet_id = oci_core_subnet.nodes.id
}
}
freeform_tags = var.freeform_tags
}
ssh_public_key = var.ssh_public_key
initial_node_labels {
key = "app"
value = "oci-cis-agent"
}
freeform_tags = var.freeform_tags
}
# --- Data source to retrieve node IPs after creation ---
data "oci_containerengine_node_pool" "app" {
node_pool_id = oci_containerengine_node_pool.app.id
}

View File

@@ -1,75 +0,0 @@
# -----------------------------------------------------------------------------
# OCI CIS Agent — OKE Deployment Stack
# Outputs
# -----------------------------------------------------------------------------
# --- Load Balancer ---
output "load_balancer_ip" {
description = "Public IP address of the Load Balancer"
value = oci_load_balancer_load_balancer.main.ip_address_details[0].ip_address
}
output "app_url" {
description = "Application URL (HTTPS)"
value = var.domain_name != "" ? "https://${var.domain_name}" : "https://${oci_load_balancer_load_balancer.main.ip_address_details[0].ip_address}"
}
# --- OKE Cluster ---
output "cluster_id" {
description = "OCID of the OKE cluster"
value = oci_containerengine_cluster.main.id
}
output "cluster_name" {
description = "Name of the OKE cluster"
value = oci_containerengine_cluster.main.name
}
output "node_pool_id" {
description = "OCID of the OKE node pool"
value = oci_containerengine_node_pool.app.id
}
output "kubeconfig_command" {
description = "Command to generate kubeconfig for the cluster"
value = "oci ce cluster create-kubeconfig --cluster-id ${oci_containerengine_cluster.main.id} --file $HOME/.kube/config --region ${var.region} --token-version 2.0.0 --kube-endpoint PRIVATE_ENDPOINT"
}
# --- OCIR ---
output "ocir_backend_url" {
description = "OCIR URL for the backend image"
value = "${var.region}.ocir.io/${var.ocir_namespace}/${var.ocir_repo_prefix}/backend"
}
output "ocir_frontend_url" {
description = "OCIR URL for the frontend image"
value = "${var.region}.ocir.io/${var.ocir_namespace}/${var.ocir_repo_prefix}/frontend"
}
output "ocir_docker_login_command" {
description = "Command to login to OCIR"
value = "docker login ${var.region}.ocir.io"
}
# --- Networking ---
output "vcn_id" {
description = "OCID of the VCN"
value = oci_core_vcn.main.id
}
output "nodes_subnet_id" {
description = "OCID of the nodes subnet"
value = oci_core_subnet.nodes.id
}
# --- WAF ---
output "waf_id" {
description = "OCID of the WAF"
value = oci_waf_web_app_firewall.main.id
}
# --- DNS (conditional) ---
output "dns_nameservers" {
description = "DNS Zone nameservers (set these at your domain registrar)"
value = var.domain_name != "" ? [for ns in oci_dns_zone.main[0].nameservers : ns.hostname] : []
}

View File

@@ -1,27 +0,0 @@
# -----------------------------------------------------------------------------
# OCI CIS Agent — OKE Deployment Stack
# Provider Configuration
# -----------------------------------------------------------------------------
terraform {
required_version = ">= 1.5.0"
required_providers {
oci = {
source = "oracle/oci"
version = ">= 6.0.0"
}
tls = {
source = "hashicorp/tls"
version = ">= 4.0.0"
}
}
}
provider "oci" {
tenancy_ocid = var.tenancy_ocid
user_ocid = var.user_ocid
fingerprint = var.fingerprint
private_key_path = var.private_key_path
region = var.region
}

View File

@@ -1,18 +0,0 @@
# -----------------------------------------------------------------------------
# OCI CIS Agent — OKE Deployment Stack
# OCIR: Container Image Repositories
# -----------------------------------------------------------------------------
resource "oci_artifacts_container_repository" "backend" {
compartment_id = var.compartment_ocid
display_name = "${var.ocir_repo_prefix}/backend"
is_public = false
is_immutable = false
}
resource "oci_artifacts_container_repository" "frontend" {
compartment_id = var.compartment_ocid
display_name = "${var.ocir_repo_prefix}/frontend"
is_public = false
is_immutable = false
}

View File

@@ -1,58 +0,0 @@
# =============================================================================
# OCI CIS Agent — OKE Deployment Stack
# Copy this file to terraform.tfvars and fill in your values.
# =============================================================================
# --- OCI Authentication ---
tenancy_ocid = "ocid1.tenancy.oc1..aaaaaaaaXXXXXXXX"
user_ocid = "ocid1.user.oc1..aaaaaaaaXXXXXXXX"
fingerprint = "aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99"
private_key_path = "~/.oci/oci_api_key.pem"
region = "us-ashburn-1"
# --- Compartment ---
compartment_ocid = "ocid1.compartment.oc1..aaaaaaaaXXXXXXXX"
# --- Networking (defaults are fine for most deployments) ---
# vcn_cidr = "10.0.0.0/16"
# public_subnet_cidr = "10.0.1.0/24"
# nodes_subnet_cidr = "10.0.2.0/24"
# api_subnet_cidr = "10.0.3.0/24"
# --- OKE Cluster ---
# kubernetes_version = "v1.30.1"
# cluster_name = "oci-cis-agent-oke"
# --- Node Pool ---
# node_shape = "VM.Standard3.Flex"
# node_ocpus = 2
# node_memory_gb = 16
# node_count = 3
# node_boot_volume_gb = 50
# --- SSH Key ---
ssh_public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAA... your-key-here"
# --- Application ---
# Generate with: python3 -c "import secrets; print(secrets.token_hex(64))"
app_secret = "YOUR_128_CHAR_HEX_SECRET_HERE"
# jwt_expiry_hours = 12
# app_timezone = "UTC"
# --- OCIR ---
ocir_namespace = "your-tenancy-namespace"
# ocir_repo_prefix = "oci-cis-agent"
# --- Load Balancer ---
# lb_min_bandwidth_mbps = 10
# lb_max_bandwidth_mbps = 100
# node_port = 30080
# --- DNS (optional: leave empty to skip) ---
# domain_name = "cisagent.example.com"
# --- Tags ---
# freeform_tags = {
# "Project" = "oci-cis-agent"
# "ManagedBy" = "terraform"
# }

View File

@@ -1,198 +0,0 @@
# -----------------------------------------------------------------------------
# OCI Authentication
# -----------------------------------------------------------------------------
variable "tenancy_ocid" {
description = "OCID of the OCI tenancy"
type = string
}
variable "user_ocid" {
description = "OCID of the OCI user for API authentication"
type = string
}
variable "fingerprint" {
description = "Fingerprint of the OCI API signing key"
type = string
}
variable "private_key_path" {
description = "Path to the OCI API private key PEM file"
type = string
}
variable "region" {
description = "OCI region for deployment"
type = string
default = "us-ashburn-1"
}
# -----------------------------------------------------------------------------
# Compartment
# -----------------------------------------------------------------------------
variable "compartment_ocid" {
description = "OCID of the existing compartment for all resources"
type = string
}
# -----------------------------------------------------------------------------
# Networking
# -----------------------------------------------------------------------------
variable "vcn_cidr" {
description = "CIDR block for the VCN"
type = string
default = "10.0.0.0/16"
}
variable "public_subnet_cidr" {
description = "CIDR block for the public subnet (Load Balancer)"
type = string
default = "10.0.1.0/24"
}
variable "nodes_subnet_cidr" {
description = "CIDR block for the private subnet (OKE worker nodes)"
type = string
default = "10.0.2.0/24"
}
variable "api_subnet_cidr" {
description = "CIDR block for the private subnet (OKE API endpoint)"
type = string
default = "10.0.3.0/24"
}
# -----------------------------------------------------------------------------
# OKE Cluster
# -----------------------------------------------------------------------------
variable "kubernetes_version" {
description = "Kubernetes version for the OKE cluster"
type = string
default = "v1.30.1"
}
variable "cluster_name" {
description = "Name of the OKE cluster"
type = string
default = "oci-cis-agent-oke"
}
# -----------------------------------------------------------------------------
# Node Pool
# -----------------------------------------------------------------------------
variable "node_shape" {
description = "Shape of the OKE worker nodes"
type = string
default = "VM.Standard3.Flex"
}
variable "node_ocpus" {
description = "Number of OCPUs per worker node"
type = number
default = 2
}
variable "node_memory_gb" {
description = "Memory in GB per worker node"
type = number
default = 16
}
variable "node_count" {
description = "Number of worker nodes in the node pool"
type = number
default = 3
}
variable "node_boot_volume_gb" {
description = "Boot volume size in GB per worker node"
type = number
default = 50
}
variable "ssh_public_key" {
description = "SSH public key for worker node access"
type = string
}
# -----------------------------------------------------------------------------
# Application Configuration
# -----------------------------------------------------------------------------
variable "app_secret" {
description = "Application secret key (64-byte hex string, 128 characters)"
type = string
sensitive = true
validation {
condition = can(regex("^[0-9a-fA-F]{128}$", var.app_secret))
error_message = "app_secret must be a 128-character hexadecimal string (64 bytes)."
}
}
variable "jwt_expiry_hours" {
description = "JWT token expiry time in hours"
type = number
default = 12
}
variable "app_timezone" {
description = "Timezone for the application (e.g. America/Sao_Paulo)"
type = string
default = "UTC"
}
# -----------------------------------------------------------------------------
# OCIR (Oracle Cloud Infrastructure Registry)
# -----------------------------------------------------------------------------
variable "ocir_namespace" {
description = "Object Storage namespace for OCIR (tenancy namespace)"
type = string
}
variable "ocir_repo_prefix" {
description = "Repository prefix in OCIR (e.g. oci-cis-agent)"
type = string
default = "oci-cis-agent"
}
# -----------------------------------------------------------------------------
# Load Balancer
# -----------------------------------------------------------------------------
variable "lb_min_bandwidth_mbps" {
description = "Minimum bandwidth for the flexible load balancer in Mbps"
type = number
default = 10
}
variable "lb_max_bandwidth_mbps" {
description = "Maximum bandwidth for the flexible load balancer in Mbps"
type = number
default = 100
}
variable "node_port" {
description = "NodePort for the Kubernetes frontend service (must match K8s Service spec)"
type = number
default = 30080
}
# -----------------------------------------------------------------------------
# DNS (Optional)
# -----------------------------------------------------------------------------
variable "domain_name" {
description = "Domain name for DNS zone and A record. Leave empty to skip DNS setup."
type = string
default = ""
}
# -----------------------------------------------------------------------------
# Tags
# -----------------------------------------------------------------------------
variable "freeform_tags" {
description = "Freeform tags to apply to all resources"
type = map(string)
default = {
"Project" = "oci-cis-agent"
"ManagedBy" = "terraform"
}
}

View File

@@ -1,114 +0,0 @@
# -----------------------------------------------------------------------------
# OCI CIS Agent — OKE Deployment Stack
# WAF: Web Application Firewall Policy + Association
# -----------------------------------------------------------------------------
resource "oci_waf_web_app_firewall_policy" "main" {
compartment_id = var.compartment_ocid
display_name = "cisagent-oke-waf-policy"
# --- OWASP Protection Rules ---
actions {
name = "block"
type = "RETURN_HTTP_RESPONSE"
code = 403
body {
type = "STATIC_TEXT"
text = "Blocked by WAF"
}
}
actions {
name = "allow"
type = "ALLOW"
}
# --- Request Protection: XSS ---
request_protection {
rules {
name = "xss-protection"
type = "PROTECTION"
action_name = "block"
is_body_inspection_enabled = true
protection_capabilities {
key = "941110"
version = 1
}
protection_capabilities {
key = "941100"
version = 1
}
protection_capabilities {
key = "941160"
version = 1
}
}
# --- Request Protection: SQL Injection ---
rules {
name = "sqli-protection"
type = "PROTECTION"
action_name = "block"
is_body_inspection_enabled = true
protection_capabilities {
key = "942110"
version = 1
}
protection_capabilities {
key = "942120"
version = 1
}
protection_capabilities {
key = "942130"
version = 1
}
}
# --- Request Protection: Path Traversal ---
rules {
name = "path-traversal-protection"
type = "PROTECTION"
action_name = "block"
is_body_inspection_enabled = true
protection_capabilities {
key = "930100"
version = 1
}
protection_capabilities {
key = "930110"
version = 1
}
}
}
# --- Rate Limiting: 300 requests/minute ---
request_rate_limiting {
rules {
name = "rate-limit-300-per-minute"
type = "RATE_LIMITING"
action_name = "block"
configurations {
period_in_seconds = 60
requests_limit = 300
action_duration_in_seconds = 60
}
}
}
freeform_tags = var.freeform_tags
}
# --- Associate WAF with Load Balancer ---
resource "oci_waf_web_app_firewall" "main" {
compartment_id = var.compartment_ocid
display_name = "cisagent-oke-waf"
backend_type = "LOAD_BALANCER"
load_balancer_id = oci_load_balancer_load_balancer.main.id
web_app_firewall_policy_id = oci_waf_web_app_firewall_policy.main.id
freeform_tags = var.freeform_tags
}