mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-10 04:49:19 -08:00
175 lines
6.2 KiB
Nix
175 lines
6.2 KiB
Nix
{ config, tf, meta, kw, pkgs, lib, sources, ... }: with lib; let
|
|
oci-root = meta.deploy.targets.oci-root.tf;
|
|
in
|
|
{
|
|
deploy.tf =
|
|
let
|
|
compartment_id = oci-root.resources.oci_kw_compartment.importAttr "id";
|
|
inherit (tf.lib.tf) terraformExpr;
|
|
in
|
|
{
|
|
deploy.systems.rinnosuke = {
|
|
lustrate = {
|
|
enable = true;
|
|
connection = tf.resources.rinnosuke.connection.set;
|
|
};
|
|
connection = {
|
|
port = 62954;
|
|
};
|
|
};
|
|
providers.oci = {
|
|
inputs = {
|
|
tenancy_ocid = oci-root.outputs.oci_tenancy.import;
|
|
user_ocid = oci-root.resources.oci_kw_user.importAttr "id";
|
|
fingerprint = oci-root.resources.oci_kw_apikey.importAttr "fingerprint";
|
|
region = oci-root.outputs.oci_region.import;
|
|
private_key_path = oci-root.resources.oci_kw_key_file.importAttr "filename";
|
|
};
|
|
};
|
|
resources = mkMerge [{
|
|
cloudinit = {
|
|
provider = "cloudinit";
|
|
type = "config";
|
|
dataSource = true;
|
|
inputs = {
|
|
part = singleton {
|
|
content_type = "text/cloud-config";
|
|
content = "#cloud-config\n" + builtins.toJSON {
|
|
disable_root = false;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
availability_domain = {
|
|
provider = "oci";
|
|
type = "identity_availability_domain";
|
|
dataSource = true;
|
|
inputs = {
|
|
inherit compartment_id;
|
|
ad_number = 2;
|
|
};
|
|
};
|
|
generic_image = {
|
|
provider = "oci";
|
|
type = "core_images";
|
|
dataSource = true;
|
|
inputs = {
|
|
inherit compartment_id;
|
|
inherit (tf.resources.rinnosuke.inputs) shape;
|
|
operating_system = "Canonical Ubuntu"; # "Oracle Linux"
|
|
sort_by = "TIMECREATED";
|
|
sort_order = "DESC";
|
|
};
|
|
};
|
|
rinnosuke_vnic = {
|
|
provider = "oci";
|
|
type = "core_vnic_attachments";
|
|
dataSource = true;
|
|
inputs = {
|
|
inherit compartment_id;
|
|
instance_id = tf.resources.rinnosuke.refAttr "id";
|
|
};
|
|
};
|
|
rinnosuke_ipv6 = {
|
|
provider = "oci";
|
|
type = "core_ipv6";
|
|
inputs = {
|
|
vnic_id = tf.resources.rinnosuke_vnic.refAttr "vnic_attachments[0].vnic_id";
|
|
display_name = config.networking.hostName;
|
|
ip_address = terraformExpr ''cidrhost("${oci-root.resources.oci_kw_subnet.importAttr "ipv6cidr_block"}", 7)'';
|
|
};
|
|
};
|
|
rinnosuke = {
|
|
provider = "oci";
|
|
type = "core_instance";
|
|
inputs = {
|
|
inherit compartment_id;
|
|
extended_metadata = { };
|
|
metadata = {
|
|
ssh_authorized_keys = concatStringsSep "\n" config.users.users.root.openssh.authorizedKeys.keys;
|
|
user_data = tf.resources.cloudinit.refAttr "rendered";
|
|
};
|
|
shape = "VM.Standard.E2.1.Micro";
|
|
shape_config = {
|
|
memory_in_gbs = 1;
|
|
ocpus = 1;
|
|
};
|
|
source_details = {
|
|
source_type = "image";
|
|
source_id = tf.resources.generic_image.refAttr "images[0].id";
|
|
boot_volume_size_in_gbs = 50; # min 50GB, up to 200GB free
|
|
};
|
|
create_vnic_details = [
|
|
{
|
|
assign_public_ip = true;
|
|
subnet_id = oci-root.resources.oci_kw_subnet.importAttr "id";
|
|
private_ip = terraformExpr ''cidrhost("${oci-root.resources.oci_kw_subnet.importAttr "cidr_block"}", 3)'';
|
|
nsg_ids = [
|
|
(tf.resources.firewall_group.refAttr "id")
|
|
];
|
|
}
|
|
];
|
|
availability_domain = tf.resources.availability_domain.refAttr "name";
|
|
};
|
|
lifecycle.ignoreChanges = [
|
|
"source_details[0].source_id"
|
|
];
|
|
connection = {
|
|
type = "ssh";
|
|
user = "root";
|
|
host = tf.lib.tf.terraformSelf "public_ip";
|
|
timeout = "5m";
|
|
};
|
|
};
|
|
firewall_group = {
|
|
provider = "oci";
|
|
type = "core_network_security_group";
|
|
inputs = {
|
|
display_name = "${config.networking.hostName} firewall group";
|
|
inherit compartment_id;
|
|
vcn_id = oci-root.resources.oci_vcn.importAttr "id";
|
|
};
|
|
};
|
|
}
|
|
(
|
|
let
|
|
protoValues = {
|
|
TCP = 6;
|
|
UDP = 17;
|
|
};
|
|
inherit (config.networking) firewall;
|
|
ipv4 = "0.0.0.0/0";
|
|
ipv6 = "::/0";
|
|
mapPort = source: protocol: port: {
|
|
provider = "oci";
|
|
type = "core_network_security_group_security_rule";
|
|
inputs = {
|
|
network_security_group_id = tf.resources.firewall_group.refAttr "id";
|
|
inherit protocol source;
|
|
direction = "INGRESS";
|
|
${if protocol == protoValues.TCP then "tcp_options" else "udp_options"} = {
|
|
destination_port_range =
|
|
if isAttrs port then {
|
|
min = port.from;
|
|
max = port.to;
|
|
} else {
|
|
min = port;
|
|
max = port;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
mapAll = protocol: port: [ (mapPort ipv4 protocol port) (mapPort ipv6 protocol port) ];
|
|
mapAllForInterface =
|
|
let
|
|
protos = [ "TCP" "UDP" ];
|
|
types = [ "Ports" "PortRanges" ];
|
|
in
|
|
interface: concatMap (type: concatMap (proto: (concatMap (port: (mapAll protoValues.${proto}) port) interface."allowed${proto}${type}")) protos) types;
|
|
rules = concatMap mapAllForInterface ([ firewall ] ++ map (interface: firewall.interfaces.${interface}) config.network.firewall.public.interfaces);
|
|
# TODO: use `count` and index into a fancy json or something?
|
|
in
|
|
listToAttrs (imap0 (i: rule: nameValuePair "firewall${toString i}" rule) rules)
|
|
)];
|
|
};
|
|
}
|