From 995950b25bbb7f914a2057760ef464b77ee07b76 Mon Sep 17 00:00:00 2001 From: Djeeberjr Date: Sat, 3 Dec 2022 14:54:36 +0100 Subject: [PATCH] initial commit --- .gitignore | 38 ++++++++++++++ README.md | 1 + a1_flex.tf | 31 +++++++++++ data.tf | 29 ++++++++++ dns.tf | 21 ++++++++ e2_micro.tf | 31 +++++++++++ provider.tf | 24 +++++++++ variables.tf | 79 ++++++++++++++++++++++++++++ vcn.tf | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 400 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 a1_flex.tf create mode 100644 data.tf create mode 100644 dns.tf create mode 100644 e2_micro.tf create mode 100644 provider.tf create mode 100644 variables.tf create mode 100644 vcn.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61482ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ + +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Terraform lock file +.terraform.lock.hcl + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc diff --git a/README.md b/README.md new file mode 100644 index 0000000..b2ca3c7 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Terraform files to easily create resources on OCI with whats available on the free-tier. \ No newline at end of file diff --git a/a1_flex.tf b/a1_flex.tf new file mode 100644 index 0000000..c856f5c --- /dev/null +++ b/a1_flex.tf @@ -0,0 +1,31 @@ +resource "oci_core_instance" "a1_flex_instances" { + for_each = var.a1_flex + + display_name = each.key + shape = "VM.Standard.A1.Flex" + compartment_id = var.compartment_ocid + + availability_domain = data.oci_identity_availability_domains.ads.availability_domains[each.value.ad].name + # fault_domain = "FAULT-DOMAIN-3" + + metadata = { + "ssh_authorized_keys" = var.ssh_key + } + + create_vnic_details { + assign_public_ip = "true" + display_name = each.key + hostname_label = each.key + subnet_id = oci_core_subnet.list[each.value.vcn].id + } + + shape_config { + memory_in_gbs = each.value.ram + ocpus = each.value.cpu + } + + source_details { + source_id = data.oci_core_images.latest_ubuntu_image_arm_minimal.images.0.id + source_type = "image" + } +} diff --git a/data.tf b/data.tf new file mode 100644 index 0000000..7b5183b --- /dev/null +++ b/data.tf @@ -0,0 +1,29 @@ +data "oci_identity_availability_domains" "ads" { + compartment_id = var.compartment_ocid +} + +data "oci_core_images" "latest_ubuntu_image_amd_minimal" { + compartment_id = var.compartment_ocid + operating_system = "Canonical Ubuntu" + shape = "VM.Standard.E2.1.Micro" + sort_by = "TIMECREATED" + + filter { + name = "display_name" + values = ["Minimal"] + regex = true + } +} + +data "oci_core_images" "latest_ubuntu_image_arm_minimal" { + compartment_id = var.compartment_ocid + operating_system = "Canonical Ubuntu" + shape = "VM.Standard.A1.Flex" + sort_by = "TIMECREATED" + + filter { + name = "display_name" + values = ["Minimal"] + regex = true + } +} diff --git a/dns.tf b/dns.tf new file mode 100644 index 0000000..68e7bb0 --- /dev/null +++ b/dns.tf @@ -0,0 +1,21 @@ +resource "cloudflare_record" "dns_a1_flex" { + for_each = var.a1_flex + + zone_id = var.cloudflare_zone_id + + name = "${each.key}.${var.base_domain}" + value = oci_core_instance.a1_flex_instances[each.key].public_ip + type = "A" + ttl = 1 # For automatic +} + +resource "cloudflare_record" "dns_e2_micro" { + for_each = var.e2_micro + + zone_id = var.cloudflare_zone_id + + name = "${each.key}.${var.base_domain}" + value = oci_core_instance.e2_micro_instances[each.key].public_ip + type = "A" + ttl = 1 # For automatic +} diff --git a/e2_micro.tf b/e2_micro.tf new file mode 100644 index 0000000..1a2241d --- /dev/null +++ b/e2_micro.tf @@ -0,0 +1,31 @@ +resource "oci_core_instance" "e2_micro_instances" { + for_each = var.e2_micro + + display_name = each.key + shape = "VM.Standard.E2.1.Micro" + compartment_id = var.compartment_ocid + + availability_domain = data.oci_identity_availability_domains.ads.availability_domains[each.value.ad].name + # fault_domain = "FAULT-DOMAIN-3" + + metadata = { + "ssh_authorized_keys" = var.ssh_key + } + + create_vnic_details { + assign_public_ip = "true" + display_name = each.key + hostname_label = each.key + subnet_id = oci_core_subnet.list[each.value.vcn].id + } + + shape_config { + memory_in_gbs = 1 + ocpus = 1 + } + + source_details { + source_id = data.oci_core_images.latest_ubuntu_image_amd_minimal.images.0.id + source_type = "image" + } +} diff --git a/provider.tf b/provider.tf new file mode 100644 index 0000000..9ceffda --- /dev/null +++ b/provider.tf @@ -0,0 +1,24 @@ +terraform { + required_providers { + oci = { + source = "oracle/oci" + version = "~> 4.100.0" + } + cloudflare = { + source = "cloudflare/cloudflare" + version = "~> 3.0" + } + } +} + +provider "oci" { + tenancy_ocid = var.compartment_ocid + user_ocid = var.user_ocid + fingerprint = var.fingerprint_oci + private_key_path = var.private_key_path_oci + region = var.region_oci +} + +provider "cloudflare" { + api_token = var.cloudflare_api_token +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..3ca6735 --- /dev/null +++ b/variables.tf @@ -0,0 +1,79 @@ +variable "compartment_ocid" { + type = string + description = "Equal to the Tenancy ocid" +} + +variable "user_ocid" { + type = string + description = "The User ocid" +} + +variable "fingerprint_oci" { + type = string + description = "The fingerprint of the key used in OCI provider" +} + +variable "private_key_path_oci" { + type = string + description = "Path to the private key used in OCI provider" +} + +variable "region_oci" { + type = string + description = "Region to use in OCI provider" +} + +variable "cloudflare_api_token" { + type = string + description = "cloudflare API token" +} + +variable "cloudflare_zone_id" { + type = string + description = "Cloudflare zone id" +} + +variable "base_domain" { + type = string + description = "The base domain to set the dns records to e.g. 'example.com' " +} + +variable "ssh_key" { + type = string + description = "Public ssh key to add" +} + +variable "e2_micro" { + type = map(object({ + vcn = string + ad = number + })) + description = "VM.Standard.E2.1.Micro" + default = {} +} + +variable "a1_flex" { + type = map(object({ + vcn = string + cpu = string + ram = string + ad = number + })) + description = "VM.Standard.A1.Flex" + default = {} +} + +variable "vcn" { + type = map(object({ + cidr_block = string + firewall_rules = list(object({ + description = string + is_udp = bool + cidr = string + port_min = number + port_max = number + })) + })) + + default = {} +} diff --git a/vcn.tf b/vcn.tf new file mode 100644 index 0000000..14dc919 --- /dev/null +++ b/vcn.tf @@ -0,0 +1,146 @@ +resource "oci_core_vcn" "list" { + for_each = var.vcn + + compartment_id = var.compartment_ocid + display_name = "VCN ${each.key}" + cidr_blocks = [each.value.cidr_block] + dns_label = each.key +} + + +resource "oci_core_subnet" "list" { + for_each = var.vcn + + compartment_id = var.compartment_ocid + vcn_id = oci_core_vcn.list[each.key].id + cidr_block = each.value.cidr_block + display_name = "Subnet ${each.key}" + dns_label = each.key +} + +resource "oci_core_internet_gateway" "list" { + for_each = var.vcn + + compartment_id = var.compartment_ocid + vcn_id = oci_core_vcn.list[each.key].id +} + +resource "oci_core_default_route_table" "list" { + for_each = var.vcn + + manage_default_resource_id = oci_core_vcn.list[each.key].default_route_table_id + compartment_id = var.compartment_ocid + + route_rules { + destination = "0.0.0.0/0" + destination_type = "CIDR_BLOCK" + network_entity_id = oci_core_internet_gateway.list[each.key].id + } +} + +resource "oci_core_default_security_list" "list" { + for_each = var.vcn + + manage_default_resource_id = oci_core_vcn.list[each.key].default_security_list_id + compartment_id = var.compartment_ocid + + egress_security_rules { + destination = "0.0.0.0/0" + destination_type = "CIDR_BLOCK" + protocol = "all" + stateless = false + } + + ingress_security_rules { + protocol = "1" # ICMP + source = "172.16.2.0/24" + source_type = "CIDR_BLOCK" + stateless = false + + icmp_options { + code = -1 + type = 3 + } + } + + ingress_security_rules { + protocol = "1" # ICMP + source = "0.0.0.0/0" + source_type = "CIDR_BLOCK" + stateless = false + + icmp_options { + code = 4 + type = 3 + } + } + + ingress_security_rules { + description = "SSH" + protocol = "6" # TCP + source = "0.0.0.0/0" + source_type = "CIDR_BLOCK" + stateless = false + + tcp_options { + max = 22 + min = 22 + } + } + + + ingress_security_rules { + description = "HTTPS" + protocol = "6" # TCP + source = "0.0.0.0/0" + source_type = "CIDR_BLOCK" + stateless = false + + tcp_options { + max = 443 + min = 443 + } + } + + ingress_security_rules { + description = "HTTPS" + protocol = "6" # TCP + source = "0.0.0.0/0" + source_type = "CIDR_BLOCK" + stateless = false + + tcp_options { + max = 80 + min = 80 + } + } + + dynamic "ingress_security_rules" { + for_each = each.value.firewall_rules + + content { + description = ingress_security_rules.value.description + protocol = ingress_security_rules.value.is_udp ? "17" : "6" + source = ingress_security_rules.value.cidr + source_type = "CIDR_BLOCK" + + dynamic "tcp_options" { + for_each = ingress_security_rules.value.is_udp ? [] : [1] + content{ + max = ingress_security_rules.value.port_max + min = ingress_security_rules.value.port_min + } + } + + dynamic "udp_options"{ + for_each = ingress_security_rules.value.is_udp ? [1] : [] + + content{ + max = ingress_security_rules.value.port_max + min = ingress_security_rules.value.port_min + } + } + + } + } +}