initial commit
This commit is contained in:
commit
87ebb35016
37
.drone.yml
Normal file
37
.drone.yml
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
kind: pipeline
|
||||
name: check
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: whitespace
|
||||
pull: always
|
||||
image: thegeeklab/alpine-tools
|
||||
commands:
|
||||
- git diff-tree --check $(git hash-object -t tree /dev/null) HEAD
|
||||
|
||||
- name: terraform
|
||||
pull: always
|
||||
image: jmccann/drone-terraform:8
|
||||
settings:
|
||||
actions:
|
||||
- validate
|
||||
tf_version: 1.2.0
|
||||
|
||||
node:
|
||||
zone: mgmt
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/main
|
||||
- refs/tags/**
|
||||
- refs/pull/**
|
||||
|
||||
---
|
||||
kind: signature
|
||||
hmac: ec825d5879e3dc1d26bdc619143cf2ea41d5183c2d7b892498b21103379675c2
|
||||
|
||||
...
|
11
.gitignore
vendored
Executable file
11
.gitignore
vendored
Executable file
@ -0,0 +1,11 @@
|
||||
/terraform/.terraform
|
||||
|
||||
*.retry
|
||||
*.tfvars
|
||||
*.tfstate
|
||||
.terraform.lock.hcl
|
||||
|
||||
.vaultpasswd
|
||||
.envrc
|
||||
|
||||
/galaxy
|
1
.prettierignore
Normal file
1
.prettierignore
Normal file
@ -0,0 +1 @@
|
||||
.drone*
|
4
.renovaterc.json
Normal file
4
.renovaterc.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["github>thegeeklab/renovate-presets:ansible"]
|
||||
}
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Robert Kaussow <mail@thegeeklab.de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
13
README.md
Normal file
13
README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# hcloud-server-tf
|
||||
|
||||
[![Build Status](https://drone.rknet.org/api/badges/infra/hcloud_server_tf/status.svg)](https://drone.rknet.org/infra/hcloud_server_tf)
|
||||
|
||||
Terraform module to provision Hetzner Cloud servers.
|
||||
|
||||
## Usage
|
||||
|
||||
This [Terraform module](https://www.terraform.io/docs/language/modules/syntax.html) is used in our deployment repos to avoid duplicate resource definitions and simplify maintenance.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](https://github.com/ansible/galaxy/blob/main/LICENSE) file for details.
|
8
data.tf
Normal file
8
data.tf
Normal file
@ -0,0 +1,8 @@
|
||||
data "cloudflare_zones" "zones" {
|
||||
for_each = toset(try(var.cloudflare_zones, []))
|
||||
|
||||
filter {
|
||||
name = each.key
|
||||
status = "active"
|
||||
}
|
||||
}
|
133
main.tf
Normal file
133
main.tf
Normal file
@ -0,0 +1,133 @@
|
||||
locals {
|
||||
zones = {
|
||||
for zone in try(data.cloudflare_zones.zones, []) : zone.zones[0].name => zone.zones[0].id
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
server_volumes = flatten([
|
||||
for server_key, server in var.server : [
|
||||
for volume_key, volume in try(server.volumes, []) : {
|
||||
volume_name = volume.name
|
||||
volume_size = volume.size
|
||||
server_id = hcloud_server.server[server.name].id
|
||||
}
|
||||
]
|
||||
])
|
||||
}
|
||||
|
||||
locals {
|
||||
server_domains = flatten([
|
||||
for server_key, server in var.server : [
|
||||
for domain_key, domain in try(server.domains, []) : {
|
||||
record_id = try(domain.id, domain.name)
|
||||
record_name = domain.name
|
||||
record_type = domain.type
|
||||
record_value = domain.value
|
||||
record_ttl = try(domain.ttl, 1)
|
||||
zone_id = local.zones[try(domain.zone_name, var.cloudflare_default_zone)]
|
||||
}
|
||||
]
|
||||
])
|
||||
}
|
||||
|
||||
resource "hcloud_placement_group" "group" {
|
||||
for_each = { for key, row in var.server : row.name => row if contains(keys(row), "placement_group") }
|
||||
|
||||
name = each.value.placement_group
|
||||
type = "spread"
|
||||
}
|
||||
|
||||
resource "hcloud_server" "server" {
|
||||
for_each = { for row in var.server : row.name => row }
|
||||
depends_on = [hcloud_ssh_key.key]
|
||||
|
||||
name = each.value.name
|
||||
server_type = try(each.value.type, "cx11")
|
||||
image = try(each.value.image, "rocky-9")
|
||||
datacenter = try(each.value.datacenter, "fsn1-dc14")
|
||||
ssh_keys = var.server_keys
|
||||
backups = try(each.value.backups, true)
|
||||
keep_disk = try(each.value.keep_disk, false)
|
||||
placement_group_id = try(hcloud_placement_group.group[each.value.placement_group].id, null)
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [ssh_keys]
|
||||
}
|
||||
|
||||
labels = merge(
|
||||
{
|
||||
provisioner = "ansible"
|
||||
project = var.hcloud_project
|
||||
deploygroup = try(each.value.deploygroup, "1")
|
||||
},
|
||||
{
|
||||
for index, service in try(each.value.services, []) : "service_${index + 1}" => service
|
||||
},
|
||||
{
|
||||
for index, group in try(each.value.groups, []) : "group_${index + 1}" => group
|
||||
},
|
||||
try(each.value.labels, {})
|
||||
)
|
||||
}
|
||||
|
||||
resource "hcloud_volume" "volume" {
|
||||
for_each = { for row in local.server_volumes : row.volume_name => row }
|
||||
|
||||
name = each.value.volume_name
|
||||
size = each.value.volume_size
|
||||
server_id = each.value.server_id
|
||||
}
|
||||
|
||||
resource "hcloud_ssh_key" "key" {
|
||||
for_each = { for row in toset(var.ssh_keys) : element(split(" ", row), 2) => row }
|
||||
|
||||
name = each.key
|
||||
public_key = "${element(split(" ", each.value), 0)} ${element(split(" ", each.value), 1)}"
|
||||
}
|
||||
|
||||
resource "hcloud_rdns" "serverv4" {
|
||||
for_each = { for row in var.server : row.name => row }
|
||||
|
||||
server_id = hcloud_server.server[each.value.name].id
|
||||
ip_address = hcloud_server.server[each.value.name].ipv4_address
|
||||
dns_ptr = "${each.value.name}.${local.zones[try(each.value.dns_zone, var.cloudflare_default_zone)]}"
|
||||
}
|
||||
|
||||
resource "hcloud_rdns" "serverv6" {
|
||||
for_each = { for row in var.server : row.name => row }
|
||||
|
||||
server_id = hcloud_server.server[each.value.name].id
|
||||
ip_address = hcloud_server.server[each.value.name].ipv6_address
|
||||
dns_ptr = "${each.value.name}.${local.zones[try(each.value.dns_zone, var.cloudflare_default_zone)]}"
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "serverv4" {
|
||||
for_each = { for row in var.server : row.name => row }
|
||||
|
||||
zone_id = local.zones[try(each.value.dns_zone, var.cloudflare_default_zone)]
|
||||
name = each.value.name
|
||||
value = hcloud_server.server[each.value.name].ipv4_address
|
||||
type = "A"
|
||||
ttl = 1
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "serverv6" {
|
||||
for_each = { for row in var.server : row.name => row }
|
||||
|
||||
zone_id = local.zones[try(each.value.dns_zone, var.cloudflare_default_zone)]
|
||||
name = each.value.name
|
||||
value = hcloud_server.server[each.value.name].ipv6_address
|
||||
type = "AAAA"
|
||||
ttl = 1
|
||||
}
|
||||
|
||||
resource "cloudflare_record" "record" {
|
||||
for_each = { for row in local.server_domains : row.record_id => row }
|
||||
|
||||
zone_id = each.value.zone_id
|
||||
name = each.value.record_name
|
||||
value = each.value.record_value
|
||||
type = each.value.record_type
|
||||
ttl = each.value.record_ttl
|
||||
}
|
9
outputs.tf
Normal file
9
outputs.tf
Normal file
@ -0,0 +1,9 @@
|
||||
output "output" {
|
||||
value = {
|
||||
for server_key, server in hcloud_server.server : server_key => server
|
||||
}
|
||||
}
|
||||
|
||||
output "zones" {
|
||||
value = local.zones
|
||||
}
|
7
providers.tf
Normal file
7
providers.tf
Normal file
@ -0,0 +1,7 @@
|
||||
provider "hcloud" {
|
||||
token = var.hcloud_token
|
||||
}
|
||||
|
||||
provider "cloudflare" {
|
||||
api_token = var.cloudflare_api_token
|
||||
}
|
31
variables.tf
Normal file
31
variables.tf
Normal file
@ -0,0 +1,31 @@
|
||||
variable "hcloud_token" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "hcloud_project" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "cloudflare_api_token" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "cloudflare_zones" {
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "server" {
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "cloudflare_default_zone" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "server_keys" {
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "ssh_keys" {
|
||||
type = list(string)
|
||||
}
|
10
versions.tf
Normal file
10
versions.tf
Normal file
@ -0,0 +1,10 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
cloudflare = {
|
||||
source = "cloudflare/cloudflare"
|
||||
}
|
||||
hcloud = {
|
||||
source = "hetznercloud/hcloud"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user