more real world exampls; fix scanner when scanning empty character in lexer
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1 +0,0 @@
|
||||
example/real_world_stuff/* filter=git-crypt diff=git-crypt
|
||||
|
||||
@@ -18,15 +18,16 @@ To run tests simply run `nix-shell --run 'tree-sitter test'`.
|
||||
|
||||
## Compliance
|
||||
|
||||
The directory `example/real_world_stuff` contains a corpus of hcl files that I found with the github query `user:hashicorp language:HCL`. Just to be sure I encrypted them using `git-crypt`.
|
||||
The directory `example/real_world_stuff` contains a corpus of hcl files that I found with the github query `language:HCL` for users `coreos` and `hashicorp`
|
||||
|
||||
Given that some language features are still missing ( see TODO ) there are some expected parse errors:
|
||||
|
||||
```bash
|
||||
nix-shell --run 'tree-sitter parse --quiet --stat example/real_world_stuff/*'
|
||||
nix-shell --run 'tree-sitter parse --quiet --stat example/real_world_stuff/*/*'
|
||||
...
|
||||
...
|
||||
Total parses: 886; successful parses: 801; failed parses: 85; success percentage: 90.41%
|
||||
Total parses: 1130; successful parses: 1053; failed parses: 77; success percentage: 93.19%
|
||||
|
||||
```
|
||||
|
||||
The aim is to build unit testcases from selected failure classes and slowly get to 100%.
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
terraform {
|
||||
required_version = ">= 0.10.7"
|
||||
}
|
||||
|
||||
provider "archive" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "external" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "ignition" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "local" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "null" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "random" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "template" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "tls" {
|
||||
version = "1.0.1"
|
||||
}
|
||||
|
||||
variable "tectonic_config_version" {
|
||||
description = <<EOF
|
||||
(internal) This declares the version of the global configuration variables.
|
||||
It has no impact on generated assets but declares the version contract of the configuration.
|
||||
EOF
|
||||
|
||||
default = "1.0"
|
||||
}
|
||||
|
||||
variable "tectonic_image_re" {
|
||||
description = <<EOF
|
||||
(internal) Regular expression used to extract repo and tag components
|
||||
EOF
|
||||
|
||||
type = "string"
|
||||
default = "/^([^/]+/[^/]+):(.*)$/"
|
||||
}
|
||||
|
||||
variable "tectonic_container_images" {
|
||||
description = "(internal) Container images to use"
|
||||
type = "map"
|
||||
|
||||
default = {
|
||||
addon_resizer = "gcr.io/google_containers/addon-resizer:2.1"
|
||||
awscli = "quay.io/coreos/awscli:025a357f05242fdad6a81e8a6b520098aa65a600"
|
||||
gcloudsdk = "google/cloud-sdk:178.0.0-alpine"
|
||||
bootkube = "quay.io/coreos/bootkube:v0.10.0"
|
||||
tnc_operator = "quay.io/coreos/tectonic-node-controller-operator-dev:c3cee2bc5673011e88ac7b0ab1659c2c7243a499"
|
||||
etcd_cert_signer = "quay.io/coreos/kube-etcd-signer-server:678cc8e6841e2121ebfdb6e2db568fce290b67d6"
|
||||
etcd = "quay.io/coreos/etcd:v3.2.14"
|
||||
hyperkube = "openshift/origin-node:latest"
|
||||
kube_core_renderer = "quay.io/coreos/kube-core-renderer-dev:c3cee2bc5673011e88ac7b0ab1659c2c7243a499"
|
||||
kube_core_operator = "quay.io/coreos/kube-core-operator-dev:c3cee2bc5673011e88ac7b0ab1659c2c7243a499"
|
||||
tectonic_channel_operator = "quay.io/coreos/tectonic-channel-operator-dev:c3cee2bc5673011e88ac7b0ab1659c2c7243a499"
|
||||
kube_addon_operator = "quay.io/coreos/kube-addon-operator-dev:c3cee2bc5673011e88ac7b0ab1659c2c7243a499"
|
||||
tectonic_alm_operator = "quay.io/coreos/tectonic-alm-operator:v0.3.1"
|
||||
tectonic_ingress_controller_operator = "quay.io/coreos/tectonic-ingress-controller-operator-dev:c3cee2bc5673011e88ac7b0ab1659c2c7243a499"
|
||||
tectonic_utility_operator = "quay.io/coreos/tectonic-utility-operator-dev:c3cee2bc5673011e88ac7b0ab1659c2c7243a499"
|
||||
tectonic_network_operator = "quay.io/coreos/tectonic-network-operator-dev:c3cee2bc5673011e88ac7b0ab1659c2c7243a499"
|
||||
}
|
||||
}
|
||||
|
||||
variable "tectonic_container_base_images" {
|
||||
description = "(internal) Base images of the components to use"
|
||||
type = "map"
|
||||
|
||||
default = {
|
||||
tectonic_monitoring_auth = "quay.io/coreos/tectonic-monitoring-auth"
|
||||
config_reload = "quay.io/coreos/configmap-reload"
|
||||
addon_resizer = "quay.io/coreos/addon-resizer"
|
||||
kube_state_metrics = "quay.io/coreos/kube-state-metrics"
|
||||
grafana = "quay.io/coreos/monitoring-grafana"
|
||||
grafana_watcher = "quay.io/coreos/grafana-watcher"
|
||||
prometheus_operator = "quay.io/coreos/prometheus-operator"
|
||||
prometheus_config_reload = "quay.io/coreos/prometheus-config-reloader"
|
||||
prometheus = "quay.io/prometheus/prometheus"
|
||||
alertmanager = "quay.io/prometheus/alertmanager"
|
||||
node_exporter = "quay.io/prometheus/node-exporter"
|
||||
kube_rbac_proxy = "quay.io/coreos/kube-rbac-proxy"
|
||||
}
|
||||
}
|
||||
|
||||
variable "tectonic_versions" {
|
||||
description = "(internal) Versions of the components to use"
|
||||
type = "map"
|
||||
|
||||
default = {
|
||||
tectonic = "1.8.4-tectonic.2"
|
||||
alm = "0.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
variable "tectonic_service_cidr" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
(optional) This declares the IP range to assign Kubernetes service cluster IPs in CIDR notation.
|
||||
The maximum size of this IP range is /12
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_cluster_cidr" {
|
||||
type = "string"
|
||||
|
||||
description = "(optional) This declares the IP range to assign Kubernetes pod IPs in CIDR notation."
|
||||
}
|
||||
|
||||
variable "tectonic_master_count" {
|
||||
type = "string"
|
||||
default = "1"
|
||||
|
||||
description = <<EOF
|
||||
The number of master nodes to be created.
|
||||
This applies only to cloud platforms.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_worker_count" {
|
||||
type = "string"
|
||||
default = "3"
|
||||
|
||||
description = <<EOF
|
||||
The number of worker nodes to be created.
|
||||
This applies only to cloud platforms.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_etcd_count" {
|
||||
type = "string"
|
||||
default = "0"
|
||||
|
||||
description = <<EOF
|
||||
The number of etcd nodes to be created.
|
||||
If set to zero, the count of etcd nodes will be determined automatically.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_base_domain" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The base DNS domain of the cluster. It must NOT contain a trailing period. Some
|
||||
DNS providers will automatically add this if necessary.
|
||||
|
||||
Example: `openshift.example.com`.
|
||||
|
||||
Note: This field MUST be set manually prior to creating the cluster.
|
||||
This applies only to cloud platforms.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_cluster_name" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The name of the cluster.
|
||||
If used in a cloud-environment, this will be prepended to `tectonic_base_domain` resulting in the URL to the Tectonic console.
|
||||
|
||||
Note: This field MUST be set manually prior to creating the cluster.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_pull_secret_path" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
The path the pull secret file in JSON format.
|
||||
This is known to be a "Docker pull secret" as produced by the docker login [1] command.
|
||||
A sample JSON content is shown in [2].
|
||||
You can download the pull secret from your Account overview page at [3].
|
||||
|
||||
[1] https://docs.docker.com/engine/reference/commandline/login/
|
||||
|
||||
[2] https://coreos.com/os/docs/latest/registry-authentication.html#manual-registry-auth-setup
|
||||
|
||||
[3] https://account.coreos.com/overview
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_license_path" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
The path to the tectonic licence file.
|
||||
You can download the Tectonic license file from your Account overview page at [1].
|
||||
|
||||
[1] https://account.coreos.com/overview
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_container_linux_channel" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The Container Linux update channel.
|
||||
|
||||
Examples: `stable`, `beta`, `alpha`
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_container_linux_version" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The Container Linux version to use. Set to `latest` to select the latest available version for the selected update channel.
|
||||
|
||||
Examples: `latest`, `1465.6.0`
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_update_server" {
|
||||
type = "string"
|
||||
default = "https://tectonic.update.core-os.net"
|
||||
description = "(internal) The URL of the Tectonic Omaha update server"
|
||||
}
|
||||
|
||||
variable "tectonic_update_channel" {
|
||||
type = "string"
|
||||
default = "tectonic-1.9-production"
|
||||
description = "(internal) The Tectonic Omaha update channel"
|
||||
}
|
||||
|
||||
variable "tectonic_update_app_id" {
|
||||
type = "string"
|
||||
default = "6bc7b986-4654-4a0f-94b3-84ce6feb1db4"
|
||||
description = "(internal) The Tectonic Omaha update App ID"
|
||||
}
|
||||
|
||||
variable "tectonic_admin_email" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
(internal) The e-mail address used to:
|
||||
1. login as the admin user to the Tectonic Console.
|
||||
2. generate DNS zones for some providers.
|
||||
|
||||
Note: This field MUST be in all lower-case e-mail address format and set manually prior to creating the cluster.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_admin_password" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
(internal) The admin user password to login to the Tectonic Console.
|
||||
|
||||
Note: This field MUST be set manually prior to creating the cluster. Backslashes and double quotes must
|
||||
also be escaped.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ca_cert" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) The content of the PEM-encoded CA certificate, used to generate all cluster certificates.
|
||||
If left blank, a CA certificate will be automatically generated.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ca_key" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) The content of the PEM-encoded CA key, used to generate Tectonic all cluster certificates.
|
||||
This field is mandatory if `tectonic_ca_cert` is set.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ca_key_alg" {
|
||||
type = "string"
|
||||
default = "RSA"
|
||||
|
||||
description = <<EOF
|
||||
(optional) The algorithm used to generate tectonic_ca_key.
|
||||
The default value is currently recommended.
|
||||
This field is mandatory if `tectonic_ca_cert` is set.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_stats_url" {
|
||||
type = "string"
|
||||
default = "https://stats-collector.tectonic.com"
|
||||
description = "(internal) The Tectonic statistics collection URL to which to report."
|
||||
}
|
||||
|
||||
variable "tectonic_networking" {
|
||||
description = <<EOF
|
||||
(optional) Configures the network to be used in Tectonic. One of the following values can be used:
|
||||
|
||||
- "flannel": enables overlay networking only. This is implemented by flannel using VXLAN.
|
||||
|
||||
- "canal": enables overlay networking including network policy. Overlay is implemented by flannel using VXLAN. Network policy is implemented by Calico.
|
||||
|
||||
- "calico-ipip": [ALPHA] enables BGP based networking. Routing and network policy is implemented by Calico. Note this has been tested on bare metal installations only.
|
||||
|
||||
- "none": disables the installation of any Pod level networking layer provided by Tectonic. By setting this value, users are expected to deploy their own solution to enable network connectivity for Pods and Services.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_kubelet_debug_config" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = "(internal) debug flags for the kubelet (used in CI only)"
|
||||
}
|
||||
|
||||
variable "tectonic_ignition_master" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(internal) Ignition config file path. This is automatically generated by the installer.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ignition_worker" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(internal) Ignition config file path. This is automatically generated by the installer.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_platform" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
(internal) The internal Terraform platform type, e.g. aws or libvirt
|
||||
EOF
|
||||
}
|
||||
|
||||
// This variable is generated by tectonic internally. Do not modify
|
||||
variable "tectonic_cluster_id" {
|
||||
type = "string"
|
||||
description = "(internal) The Tectonic cluster id."
|
||||
}
|
||||
@@ -0,0 +1,610 @@
|
||||
terraform {
|
||||
required_version = ">= 0.10.7"
|
||||
}
|
||||
|
||||
provider "archive" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "external" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "ignition" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "local" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "null" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "random" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "template" {
|
||||
version = "1.0.0"
|
||||
}
|
||||
|
||||
provider "tls" {
|
||||
version = "1.0.1"
|
||||
}
|
||||
|
||||
locals {
|
||||
// The total amount of public CA certificates present in Tectonic.
|
||||
// That is all custom CAs + kube CA + etcd CA + ingress CA
|
||||
// This is a local constant, which needs to be dependency injected because TF cannot handle length() on computed values,
|
||||
// see https://github.com/hashicorp/terraform/issues/10857#issuecomment-268289775.
|
||||
tectonic_ca_count = "${length(var.tectonic_custom_ca_pem_list) + 3}"
|
||||
|
||||
tectonic_http_proxy_enabled = "${length(var.tectonic_http_proxy_address) > 0}"
|
||||
}
|
||||
|
||||
variable "tectonic_config_version" {
|
||||
description = <<EOF
|
||||
(internal) This declares the version of the global configuration variables.
|
||||
It has no impact on generated assets but declares the version contract of the configuration.
|
||||
EOF
|
||||
|
||||
default = "1.0"
|
||||
}
|
||||
|
||||
variable "tectonic_image_re" {
|
||||
description = <<EOF
|
||||
(internal) Regular expression used to extract repo and tag components
|
||||
EOF
|
||||
|
||||
type = "string"
|
||||
default = "/^([^/]+/[^/]+/[^/]+):(.*)$/"
|
||||
}
|
||||
|
||||
variable "tectonic_container_images" {
|
||||
description = "(internal) Container images to use"
|
||||
type = "map"
|
||||
|
||||
default = {
|
||||
addon_resizer = "gcr.io/google_containers/addon-resizer:2.1"
|
||||
awscli = "quay.io/coreos/awscli:025a357f05242fdad6a81e8a6b520098aa65a600"
|
||||
gcloudsdk = "google/cloud-sdk:178.0.0-alpine"
|
||||
bootkube = "quay.io/coreos/bootkube:v0.8.1"
|
||||
calico = "quay.io/calico/node:v2.6.1"
|
||||
calico_cni = "quay.io/calico/cni:v1.11.0"
|
||||
console = "quay.io/coreos/tectonic-console:v6.0.5"
|
||||
error_server = "quay.io/coreos/tectonic-error-server:1.1"
|
||||
etcd = "quay.io/coreos/etcd:v3.1.8"
|
||||
etcd_operator = "quay.io/coreos/etcd-operator:v0.5.0"
|
||||
flannel = "quay.io/coreos/flannel:v0.8.0-amd64"
|
||||
flannel_cni = "quay.io/coreos/flannel-cni:v0.2.0"
|
||||
heapster = "gcr.io/google_containers/heapster:v1.4.1"
|
||||
hyperkube = "quay.io/coreos/hyperkube:v1.9.6_coreos.0"
|
||||
identity = "quay.io/coreos/dex:v2.8.1"
|
||||
ingress_controller = "quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0-beta.17"
|
||||
kenc = "quay.io/coreos/kenc:0.0.2"
|
||||
kubedns = "gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.8"
|
||||
kubednsmasq = "gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.8"
|
||||
kubedns_sidecar = "gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.8"
|
||||
kube_version = "quay.io/coreos/kube-version:0.1.0"
|
||||
kube_version_operator = "quay.io/coreos/kube-version-operator:v1.9.6-kvo.4"
|
||||
node_agent = "quay.io/coreos/node-agent:cd69b4a0f65b0d3a3b30edfce3bb184fd2a22c26"
|
||||
pod_checkpointer = "quay.io/coreos/pod-checkpointer:e22cc0e3714378de92f45326474874eb602ca0ac"
|
||||
stats_emitter = "quay.io/coreos/tectonic-stats:6e882361357fe4b773adbf279cddf48cb50164c1"
|
||||
stats_extender = "quay.io/coreos/tectonic-stats-extender:487b3da4e175da96dabfb44fba65cdb8b823db2e"
|
||||
tectonic_channel_operator = "quay.io/coreos/tectonic-channel-operator:0.6.4"
|
||||
tectonic_etcd_operator = "quay.io/coreos/tectonic-etcd-operator:v0.0.2"
|
||||
tectonic_prometheus_operator = "quay.io/coreos/tectonic-prometheus-operator:v1.9.5"
|
||||
tectonic_cluo_operator = "quay.io/coreos/tectonic-cluo-operator:v0.3.2"
|
||||
tectonic_torcx = "quay.io/coreos/tectonic-torcx:v0.2.0"
|
||||
tectonic_alm_operator = "quay.io/coreos/tectonic-alm-operator:v0.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
variable "tectonic_container_base_images" {
|
||||
description = "(internal) Base images of the components to use"
|
||||
type = "map"
|
||||
|
||||
default = {
|
||||
tectonic_monitoring_auth = "quay.io/coreos/tectonic-monitoring-auth"
|
||||
config_reload = "quay.io/coreos/configmap-reload"
|
||||
addon_resizer = "quay.io/coreos/addon-resizer"
|
||||
kube_state_metrics = "quay.io/coreos/kube-state-metrics"
|
||||
grafana = "quay.io/coreos/monitoring-grafana"
|
||||
grafana_watcher = "quay.io/coreos/grafana-watcher"
|
||||
prometheus_operator = "quay.io/coreos/prometheus-operator"
|
||||
prometheus_config_reload = "quay.io/coreos/prometheus-config-reloader"
|
||||
prometheus = "quay.io/prometheus/prometheus"
|
||||
alertmanager = "quay.io/prometheus/alertmanager"
|
||||
node_exporter = "quay.io/prometheus/node-exporter"
|
||||
kube_rbac_proxy = "quay.io/coreos/kube-rbac-proxy"
|
||||
}
|
||||
}
|
||||
|
||||
variable "tectonic_versions" {
|
||||
description = "(internal) Versions of the components to use"
|
||||
type = "map"
|
||||
|
||||
default = {
|
||||
etcd = "3.1.8"
|
||||
kubernetes = "1.9.6+tectonic.1"
|
||||
monitoring = "1.9.5"
|
||||
tectonic = "1.9.6-tectonic.1"
|
||||
tectonic-etcd = "0.0.1"
|
||||
cluo = "0.3.2"
|
||||
alm = "0.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
variable "tectonic_service_cidr" {
|
||||
type = "string"
|
||||
default = "10.3.0.0/16"
|
||||
|
||||
description = <<EOF
|
||||
(optional) This declares the IP range to assign Kubernetes service cluster IPs in CIDR notation.
|
||||
The maximum size of this IP range is /12
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_cluster_cidr" {
|
||||
type = "string"
|
||||
default = "10.2.0.0/16"
|
||||
|
||||
description = "(optional) This declares the IP range to assign Kubernetes pod IPs in CIDR notation."
|
||||
}
|
||||
|
||||
variable "tectonic_master_count" {
|
||||
type = "string"
|
||||
default = "1"
|
||||
|
||||
description = <<EOF
|
||||
The number of master nodes to be created.
|
||||
This applies only to cloud platforms.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_worker_count" {
|
||||
type = "string"
|
||||
default = "3"
|
||||
|
||||
description = <<EOF
|
||||
The number of worker nodes to be created.
|
||||
This applies only to cloud platforms.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_etcd_count" {
|
||||
type = "string"
|
||||
default = "0"
|
||||
|
||||
description = <<EOF
|
||||
The number of etcd nodes to be created.
|
||||
If set to zero, the count of etcd nodes will be determined automatically.
|
||||
|
||||
Note: This is not supported on bare metal.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_etcd_servers" {
|
||||
description = <<EOF
|
||||
(optional) List of external etcd v3 servers to connect with (hostnames/IPs only).
|
||||
Needs to be set if using an external etcd cluster.
|
||||
Note: If this variable is defined, the installer will not create self-signed certs.
|
||||
To provide a CA certificate to trust the etcd servers, set "tectonic_etcd_ca_cert_path".
|
||||
|
||||
Example: `["etcd1", "etcd2", "etcd3"]`
|
||||
EOF
|
||||
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "tectonic_etcd_tls_enabled" {
|
||||
default = true
|
||||
|
||||
description = <<EOF
|
||||
(optional) If set to `true`, all etcd endpoints will be configured to use the "https" scheme.
|
||||
|
||||
Note: If `tectonic_experimental` is set to `true` this variable has no effect, because the experimental self-hosted etcd always uses TLS.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_etcd_ca_cert_path" {
|
||||
type = "string"
|
||||
default = "/dev/null"
|
||||
|
||||
description = <<EOF
|
||||
(optional) The path of the file containing the CA certificate for TLS communication with etcd.
|
||||
|
||||
Note: This works only when used in conjunction with an external etcd cluster.
|
||||
If set, the variable `tectonic_etcd_servers` must also be set.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_etcd_client_cert_path" {
|
||||
type = "string"
|
||||
default = "/dev/null"
|
||||
|
||||
description = <<EOF
|
||||
(optional) The path of the file containing the client certificate for TLS communication with etcd.
|
||||
|
||||
Note: This works only when used in conjunction with an external etcd cluster.
|
||||
If set, the variables `tectonic_etcd_servers`, `tectonic_etcd_ca_cert_path`, and `tectonic_etcd_client_key_path` must also be set.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_etcd_client_key_path" {
|
||||
type = "string"
|
||||
default = "/dev/null"
|
||||
|
||||
description = <<EOF
|
||||
(optional) The path of the file containing the client key for TLS communication with etcd.
|
||||
|
||||
Note: This works only when used in conjunction with an external etcd cluster.
|
||||
If set, the variables `tectonic_etcd_servers`, `tectonic_etcd_ca_cert_path`, and `tectonic_etcd_client_cert_path` must also be set.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_base_domain" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The base DNS domain of the cluster. It must NOT contain a trailing period. Some
|
||||
DNS providers will automatically add this if necessary.
|
||||
|
||||
Example: `openstack.dev.coreos.systems`.
|
||||
|
||||
Note: This field MUST be set manually prior to creating the cluster.
|
||||
This applies only to cloud platforms.
|
||||
|
||||
[Azure-specific NOTE]
|
||||
To use Azure-provided DNS, `tectonic_base_domain` should be set to `""`
|
||||
If using DNS records, ensure that `tectonic_base_domain` is set to a properly configured external DNS zone.
|
||||
Instructions for configuring delegated domains for Azure DNS can be found here: https://docs.microsoft.com/en-us/azure/dns/dns-delegate-domain-azure-dns
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_cluster_name" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The name of the cluster.
|
||||
If used in a cloud-environment, this will be prepended to `tectonic_base_domain` resulting in the URL to the Tectonic console.
|
||||
|
||||
Note: This field MUST be set manually prior to creating the cluster.
|
||||
Warning: Special characters in the name like '.' may cause errors on OpenStack platforms due to resource name constraints.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_pull_secret_path" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
The path the pull secret file in JSON format.
|
||||
This is known to be a "Docker pull secret" as produced by the docker login [1] command.
|
||||
A sample JSON content is shown in [2].
|
||||
You can download the pull secret from your Account overview page at [3].
|
||||
|
||||
[1] https://docs.docker.com/engine/reference/commandline/login/
|
||||
|
||||
[2] https://coreos.com/os/docs/latest/registry-authentication.html#manual-registry-auth-setup
|
||||
|
||||
[3] https://account.coreos.com/overview
|
||||
|
||||
Note: This field MUST be set manually prior to creating the cluster unless `tectonic_vanilla_k8s` is set to `true`.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_license_path" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
The path to the tectonic licence file.
|
||||
You can download the Tectonic license file from your Account overview page at [1].
|
||||
|
||||
[1] https://account.coreos.com/overview
|
||||
|
||||
Note: This field MUST be set manually prior to creating the cluster unless `tectonic_vanilla_k8s` is set to `true`.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_container_linux_channel" {
|
||||
type = "string"
|
||||
default = "stable"
|
||||
|
||||
description = <<EOF
|
||||
(optional) The Container Linux update channel.
|
||||
|
||||
Examples: `stable`, `beta`, `alpha`
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_container_linux_version" {
|
||||
type = "string"
|
||||
default = "latest"
|
||||
|
||||
description = <<EOF
|
||||
The Container Linux version to use. Set to `latest` to select the latest available version for the selected update channel.
|
||||
|
||||
Examples: `latest`, `1465.6.0`
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_update_server" {
|
||||
type = "string"
|
||||
default = "https://tectonic.update.core-os.net"
|
||||
description = "(internal) The URL of the Tectonic Omaha update server"
|
||||
}
|
||||
|
||||
variable "tectonic_update_channel" {
|
||||
type = "string"
|
||||
default = "tectonic-1.8-production"
|
||||
description = "(internal) The Tectonic Omaha update channel"
|
||||
}
|
||||
|
||||
variable "tectonic_update_app_id" {
|
||||
type = "string"
|
||||
default = "6bc7b986-4654-4a0f-94b3-84ce6feb1db4"
|
||||
description = "(internal) The Tectonic Omaha update App ID"
|
||||
}
|
||||
|
||||
variable "tectonic_admin_email" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
(internal) The e-mail address used to:
|
||||
1. login as the admin user to the Tectonic Console.
|
||||
2. generate DNS zones for some providers.
|
||||
|
||||
Note: This field MUST be in all lower-case e-mail address format and set manually prior to creating the cluster.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_admin_password" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
(internal) The admin user password to login to the Tectonic Console.
|
||||
|
||||
Note: This field MUST be set manually prior to creating the cluster. Backslashes and double quotes must
|
||||
also be escaped.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ca_cert" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) The content of the PEM-encoded CA certificate, used to generate Tectonic Console's server certificate.
|
||||
If left blank, a CA certificate will be automatically generated.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ca_key" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) The content of the PEM-encoded CA key, used to generate Tectonic Console's server certificate.
|
||||
This field is mandatory if `tectonic_ca_cert` is set.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ca_key_alg" {
|
||||
type = "string"
|
||||
default = "RSA"
|
||||
|
||||
description = <<EOF
|
||||
(optional) The algorithm used to generate tectonic_ca_key.
|
||||
The default value is currently recommended.
|
||||
This field is mandatory if `tectonic_ca_cert` is set.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_tls_validity_period" {
|
||||
type = "string"
|
||||
default = "26280"
|
||||
|
||||
description = <<EOF
|
||||
Validity period of the self-signed certificates (in hours).
|
||||
Default is 3 years.
|
||||
This setting is ignored if user provided certificates are used.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_vanilla_k8s" {
|
||||
default = false
|
||||
|
||||
description = <<EOF
|
||||
If set to true, a vanilla Kubernetes cluster will be deployed, omitting any Tectonic assets.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_stats_url" {
|
||||
type = "string"
|
||||
default = "https://stats-collector.tectonic.com"
|
||||
description = "(internal) The Tectonic statistics collection URL to which to report."
|
||||
}
|
||||
|
||||
variable "tectonic_ddns_server" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) This only applies if you use the modules/dns/ddns module.
|
||||
|
||||
Specifies the RFC2136 Dynamic DNS server IP/host to register IP addresses to.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ddns_key_name" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) This only applies if you use the modules/dns/ddns module.
|
||||
|
||||
Specifies the RFC2136 Dynamic DNS server key name.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ddns_key_algorithm" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) This only applies if you use the modules/dns/ddns module.
|
||||
|
||||
Specifies the RFC2136 Dynamic DNS server key algorithm.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ddns_key_secret" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) This only applies if you use the modules/dns/ddns module.
|
||||
|
||||
Specifies the RFC2136 Dynamic DNS server key secret.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_networking" {
|
||||
default = "flannel"
|
||||
|
||||
description = <<EOF
|
||||
(optional) Configures the network to be used in Tectonic. One of the following values can be used:
|
||||
|
||||
- "flannel": enables overlay networking only. This is implemented by flannel using VXLAN.
|
||||
|
||||
- "canal": [ALPHA] enables overlay networking including network policy. Overlay is implemented by flannel using VXLAN. Network policy is implemented by Calico.
|
||||
|
||||
- "calico": [ALPHA] enables BGP based networking. Routing and network policy is implemented by Calico. Note this has been tested on baremetal installations only.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_self_hosted_etcd" {
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(internal) [ALPHA] If set to one of the following values, self-hosted etcd is deployed:
|
||||
|
||||
- "enabled": Deploys a self-hosted etcd cluster.
|
||||
|
||||
- "pv_backup": Deploys a self-hosted etcd cluster including backups to Persistence Volumes.
|
||||
`tectonic_etcd_backup_size` and `tectonic_etcd_backup_storage_class` must be configured when using this setting.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_etcd_backup_size" {
|
||||
type = "string"
|
||||
description = "(optional) The size in MB of the PersistentVolume used for handling etcd backups."
|
||||
default = "512"
|
||||
}
|
||||
|
||||
variable "tectonic_etcd_backup_storage_class" {
|
||||
type = "string"
|
||||
default = ""
|
||||
description = "(optional) The name of an existing Kubernetes StorageClass that will be used for handling etcd backups."
|
||||
}
|
||||
|
||||
variable "tectonic_bootstrap_upgrade_cl" {
|
||||
type = "string"
|
||||
default = "true"
|
||||
description = "(internal) Whether to trigger a ContainerLinux upgrade on node bootstrap."
|
||||
}
|
||||
|
||||
variable "tectonic_kubelet_debug_config" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = "(internal) debug flags for the kubelet (used in CI only)"
|
||||
}
|
||||
|
||||
variable "tectonic_custom_ca_pem_list" {
|
||||
type = "list"
|
||||
default = []
|
||||
|
||||
description = <<EOF
|
||||
(optional) A list of PEM encoded CA files that will be installed in /etc/ssl/certs on etcd, master, and worker nodes.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_iscsi_enabled" {
|
||||
type = "string"
|
||||
default = "false"
|
||||
description = "(optional) Start iscsid.service to enable iscsi volume attachment."
|
||||
}
|
||||
|
||||
variable "tectonic_http_proxy_address" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) HTTP proxy address.
|
||||
|
||||
Example: `http://myproxy.example.com`
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_https_proxy_address" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) HTTPS proxy address.
|
||||
|
||||
Example: `http://myproxy.example.com`
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_no_proxy" {
|
||||
type = "list"
|
||||
default = []
|
||||
|
||||
description = <<EOF
|
||||
(optional) List of local endpoints that will not use HTTP proxy.
|
||||
|
||||
Example: `["127.0.0.1","localhost",".example.com","10.3.0.1"]`
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_ntp_servers" {
|
||||
type = "list"
|
||||
default = []
|
||||
|
||||
description = <<EOF
|
||||
(optional) If left blank, the default Container Linux NTP servers will be used.
|
||||
A list of NTP servers to be used for time synchronization on the cluster nodes.
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "tectonic_nfs_config_file" {
|
||||
type = "string"
|
||||
default = ""
|
||||
|
||||
description = <<EOF
|
||||
(optional) the path to an NFS configuration file to be placed in /etc/conf.d/nfs
|
||||
file on the CL nodes.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Workaround for https://github.com/hashicorp/hil/issues/50
|
||||
locals {
|
||||
_tectonic_nfs_config_file = "${var.tectonic_nfs_config_file != "" ? var.tectonic_nfs_config_file : "/dev/null"}"
|
||||
}
|
||||
|
||||
variable "tectonic_proxy_exclusive_units" {
|
||||
default = false
|
||||
|
||||
description = <<EOF
|
||||
(optional) When set to true, it restricts the application of proxy settings to processes started through systemd units.
|
||||
Global proxy settings will not be affected in this case.
|
||||
When set to false, the proxy settings will apply globally, including to all processes lauched by users.
|
||||
EOF
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
provider "aws" {
|
||||
region = "${var.vpc_aws_region}"
|
||||
}
|
||||
|
||||
# Declare the data source
|
||||
data "aws_availability_zones" "available" {}
|
||||
|
||||
resource "aws_vpc" "vpc" {
|
||||
cidr_block = "${var.vpc_cidr}"
|
||||
enable_dns_support = true
|
||||
enable_dns_hostnames = true
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}"
|
||||
}
|
||||
}
|
||||
|
||||
data "aws_ami" "coreos_ami" {
|
||||
most_recent = true
|
||||
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["CoreOS-stable-*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "architecture"
|
||||
values = ["x86_64"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "owner-id"
|
||||
values = ["190570271432"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_instance" "bastion" {
|
||||
# 1st available AZ
|
||||
availability_zone = "${data.aws_availability_zones.available.names[0]}"
|
||||
ami = "${data.aws_ami.coreos_ami.image_id}"
|
||||
instance_type = "${var.instance_type}"
|
||||
subnet_id = "${aws_subnet.pub_subnet_generic.id}"
|
||||
vpc_security_group_ids = ["${compact(concat(list(aws_security_group.powerdns.id), list(aws_security_group.vpn_sg.id)))}"]
|
||||
source_dest_check = false
|
||||
key_name = "${var.ssh_key}"
|
||||
user_data = "${data.ignition_config.main.rendered}"
|
||||
|
||||
depends_on = ["aws_eip.ovpn_eip"]
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-server"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_config" "main" {
|
||||
files = ["${data.ignition_file.nginx_conf.id}"]
|
||||
|
||||
systemd = ["${compact(list(
|
||||
data.ignition_systemd_unit.gateway_service.id,
|
||||
data.ignition_systemd_unit.nginx_service.id,
|
||||
data.ignition_systemd_unit.openvpn_service.id,
|
||||
data.ignition_systemd_unit.powerdns_service.id,
|
||||
data.ignition_systemd_unit.update-engine.id,
|
||||
data.ignition_systemd_unit.locksmithd.id,
|
||||
))}"]
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "update-engine" {
|
||||
name = "update-engine.service"
|
||||
mask = true
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "locksmithd" {
|
||||
name = "locksmithd.service"
|
||||
mask = true
|
||||
}
|
||||
|
||||
# IGW
|
||||
resource "aws_internet_gateway" "igw" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-igw"
|
||||
}
|
||||
}
|
||||
|
||||
# General purpose public subnet. used for OVPN access and IGW/NAT attachment.
|
||||
resource "aws_subnet" "pub_subnet_generic" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
# 1st available AZ
|
||||
availability_zone = "${data.aws_availability_zones.available.names[0]}"
|
||||
cidr_block = "10.0.255.0/24"
|
||||
map_public_ip_on_launch = true
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-vpn"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "pub_subnet_generic" {
|
||||
subnet_id = "${aws_subnet.pub_subnet_generic.id}"
|
||||
route_table_id = "${aws_route_table.pub_rt.id}"
|
||||
}
|
||||
|
||||
# public subnet route table
|
||||
resource "aws_route_table" "pub_rt" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
route {
|
||||
cidr_block = "0.0.0.0/0"
|
||||
gateway_id = "${aws_internet_gateway.igw.id}"
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-public"
|
||||
}
|
||||
}
|
||||
|
||||
# private subnets
|
||||
resource "aws_subnet" "priv_subnet" {
|
||||
count = "${var.subnet_count}"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}"
|
||||
cidr_block = "${cidrsubnet(var.vpc_cidr, 8, count.index + 100)}"
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-${count.index}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "priv_subnet" {
|
||||
count = "${var.subnet_count}"
|
||||
subnet_id = "${aws_subnet.priv_subnet.*.id[count.index]}"
|
||||
route_table_id = "${aws_route_table.priv_rt.id}"
|
||||
}
|
||||
|
||||
# private subnet route table
|
||||
resource "aws_route_table" "priv_rt" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
propagating_vgws = ["${aws_vpn_gateway.vpg.id}"]
|
||||
|
||||
route {
|
||||
cidr_block = "0.0.0.0/0"
|
||||
instance_id = "${aws_instance.bastion.id}"
|
||||
}
|
||||
|
||||
route {
|
||||
cidr_block = "${var.local_network_cidr}"
|
||||
gateway_id = "${aws_vpn_gateway.vpg.id}"
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-private"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
# Security Group
|
||||
resource "aws_security_group" "powerdns" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "powerdns_egress" {
|
||||
type = "egress"
|
||||
security_group_id = "${aws_security_group.powerdns.id}"
|
||||
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "powerdns_ingress_ssh" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.powerdns.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "powerdns_ingress_http" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.powerdns.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "powerdns_ingress_https" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.powerdns.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "powerdns_ingress_api" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.powerdns.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 8081
|
||||
to_port = 8081
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "powerdns_ingress_dns" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.powerdns.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 53
|
||||
to_port = 53
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "powerdns_ingress_dns_udp" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.powerdns.id}"
|
||||
|
||||
protocol = "udp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 53
|
||||
to_port = 53
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
data "template_file" "gateway_service" {
|
||||
template = "${file("${path.module}/resources/gateway.service")}"
|
||||
|
||||
vars {
|
||||
private_cidr = "${cidrsubnet(var.vpc_cidr, 6, 25)}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "gateway_service" {
|
||||
name = "gateway.service"
|
||||
enabled = true
|
||||
content = "${data.template_file.gateway_service.rendered}"
|
||||
}
|
||||
|
||||
data "template_file" "nginx_service" {
|
||||
template = "${file("${path.module}/resources/nginx.service")}"
|
||||
|
||||
vars {
|
||||
username = "${var.nginx_username}"
|
||||
password = "${var.nginx_password}"
|
||||
nginx_image = "${var.container_images["nginx"]}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "nginx_service" {
|
||||
name = "nginx.service"
|
||||
enabled = true
|
||||
content = "${data.template_file.nginx_service.rendered}"
|
||||
}
|
||||
|
||||
data "template_file" "nginx_conf" {
|
||||
template = "${file("${path.module}/resources/nginx.conf")}"
|
||||
}
|
||||
|
||||
data "ignition_file" "nginx_conf" {
|
||||
filesystem = "root"
|
||||
path = "/home/core/nginx-config/default.conf"
|
||||
mode = 0644
|
||||
|
||||
content {
|
||||
content = "${data.template_file.nginx_conf.rendered}"
|
||||
}
|
||||
}
|
||||
|
||||
data "template_file" "openvpn_service" {
|
||||
template = "${file("${path.module}/resources/openvpn.service")}"
|
||||
|
||||
vars {
|
||||
ip = "${aws_eip.ovpn_eip.public_ip}"
|
||||
openvpn_image = "${var.container_images["openvpn"]}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "openvpn_service" {
|
||||
name = "openvpn.service"
|
||||
enabled = true
|
||||
content = "${data.template_file.openvpn_service.rendered}"
|
||||
}
|
||||
|
||||
data "template_file" "powerdns_service" {
|
||||
template = "${file("${path.module}/resources/powerdns.service")}"
|
||||
|
||||
vars {
|
||||
dns_zone = "${var.base_domain}"
|
||||
pdns_api_key = "${var.pdns_api_key}"
|
||||
mysql_password = "${var.mysql_password}"
|
||||
powerdns_image = "${var.container_images["powerdns"]}"
|
||||
mysql_image = "${var.container_images["mysql"]}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "powerdns_service" {
|
||||
name = "powerdns.service"
|
||||
enabled = true
|
||||
content = "${data.template_file.powerdns_service.rendered}"
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
# placeholders for access_key / secret_key
|
||||
# should be fed through env var or variable file
|
||||
# https://www.terraform.io/docs/configuration/variables.html
|
||||
|
||||
variable "vpc_name" {
|
||||
description = "The name of the VPC to identify created resources."
|
||||
default = "bastion"
|
||||
}
|
||||
|
||||
variable "instance_type" {
|
||||
description = "The type of the ec2 machine."
|
||||
default = "t2.micro"
|
||||
}
|
||||
|
||||
variable "base_domain" {
|
||||
default = "tectonic-ci.de"
|
||||
description = "The base domain for this cluster's FQDN"
|
||||
}
|
||||
|
||||
variable "vpc_aws_region" {
|
||||
description = "The target AWS region for the cluster"
|
||||
default = "us-gov-west-1"
|
||||
}
|
||||
|
||||
variable "vpc_cidr" {
|
||||
default = "10.0.0.0/16"
|
||||
description = "The CIDR range used for your entire VPC"
|
||||
}
|
||||
|
||||
variable "subnet_count" {
|
||||
default = 4
|
||||
description = "Number of private subnets to pre-create"
|
||||
}
|
||||
|
||||
variable "local_network_cidr" {
|
||||
default = "10.7.0.0/16"
|
||||
description = "IP range in the network your laptop is on (dosn't actually matter unless your instances need to connect to the local network your laptop is on)"
|
||||
}
|
||||
|
||||
variable "ssh_key" {
|
||||
description = "Name of an SSH key located within the AWS region. Example: coreos-user."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "nginx_username" {
|
||||
description = "Used for retrieving the OpenVPN client config file."
|
||||
}
|
||||
|
||||
variable "nginx_password" {
|
||||
description = "Used for retrieving the OpenVPN client config file."
|
||||
}
|
||||
|
||||
variable "mysql_password" {
|
||||
description = "Used as PowerDNS backend."
|
||||
}
|
||||
|
||||
variable "pdns_api_key" {
|
||||
description = "Used by clients to communicate with the PowerDNS API."
|
||||
}
|
||||
|
||||
variable "container_images" {
|
||||
description = "Container images to use"
|
||||
type = "map"
|
||||
|
||||
default = {
|
||||
powerdns = "quay.io/coreos/pdns:20678f8bffc316579367d885ca4fcb229b1dbc1d"
|
||||
mysql = "quay.io/coreos/mysql:5.7.21"
|
||||
openvpn = "quay.io/coreos/openvpn:2.4"
|
||||
nginx = "quay.io/coreos/nginx:1.13.7-alpine"
|
||||
}
|
||||
}
|
||||
|
||||
output "ovpn_url" {
|
||||
value = "http://${aws_eip.ovpn_eip.public_ip}"
|
||||
}
|
||||
|
||||
output "base_domain" {
|
||||
value = "${var.base_domain}"
|
||||
}
|
||||
|
||||
output "vpc_id" {
|
||||
value = "${aws_vpc.vpc.id}"
|
||||
}
|
||||
|
||||
output "vpc_dns_ip" {
|
||||
value = "${aws_instance.bastion.private_ip}"
|
||||
}
|
||||
|
||||
output "dns_api_url" {
|
||||
value = "http://${aws_instance.bastion.private_ip}:8081"
|
||||
}
|
||||
|
||||
output "subnets" {
|
||||
value = "${aws_subnet.priv_subnet.*.id}"
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
resource "aws_vpn_gateway" "vpg" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
# 1st available AZ
|
||||
availability_zone = "${data.aws_availability_zones.available.names[0]}"
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-vpg"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_eip" "ovpn_eip" {
|
||||
vpc = true
|
||||
}
|
||||
|
||||
resource "aws_eip_association" "vpn_eip_assoc" {
|
||||
instance_id = "${aws_instance.bastion.id}"
|
||||
allocation_id = "${aws_eip.ovpn_eip.id}"
|
||||
}
|
||||
|
||||
resource "aws_security_group" "vpn_sg" {
|
||||
name = "ovpn-server-sg"
|
||||
description = "Allow all inbound traffic"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
ingress {
|
||||
from_port = 0
|
||||
to_port = 65535
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["${cidrsubnet(var.vpc_cidr, 6, 25)}"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 943
|
||||
to_port = 943
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 943
|
||||
to_port = 943
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 1194
|
||||
to_port = 1194
|
||||
protocol = "udp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
|
||||
# all
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-ovpn-sg"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_customer_gateway" "customer_gateway" {
|
||||
bgp_asn = 65000
|
||||
ip_address = "${aws_eip.ovpn_eip.public_ip}"
|
||||
type = "ipsec.1"
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-customer-gateway"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_vpn_connection" "main" {
|
||||
vpn_gateway_id = "${aws_vpn_gateway.vpg.id}"
|
||||
customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}"
|
||||
type = "ipsec.1"
|
||||
static_routes_only = true
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-vpn-conn"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
provider "aws" {
|
||||
region = "${var.vpc_aws_region}"
|
||||
}
|
||||
|
||||
# Declare the data source
|
||||
data "aws_availability_zones" "available" {}
|
||||
|
||||
resource "aws_vpc" "vpc" {
|
||||
cidr_block = "${var.vpc_cidr}"
|
||||
enable_dns_support = true
|
||||
enable_dns_hostnames = true
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}"
|
||||
}
|
||||
}
|
||||
|
||||
# Private DNS zone
|
||||
resource "aws_route53_zone" "priv_zone" {
|
||||
name = "${var.base_domain}"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
comment = "Managed by Terraform"
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}"
|
||||
}
|
||||
}
|
||||
|
||||
# IGW
|
||||
resource "aws_internet_gateway" "igw" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-igw"
|
||||
}
|
||||
}
|
||||
|
||||
# NAT Gateway
|
||||
resource "aws_eip" "natgw" {
|
||||
vpc = true
|
||||
}
|
||||
|
||||
resource "aws_nat_gateway" "natgw" {
|
||||
allocation_id = "${aws_eip.natgw.id}"
|
||||
subnet_id = "${aws_subnet.pub_subnet_generic.id}"
|
||||
depends_on = ["aws_internet_gateway.igw"]
|
||||
}
|
||||
|
||||
# General purpose public subnet. used for OVPN access and IGW/NAT attachment.
|
||||
resource "aws_subnet" "pub_subnet_generic" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
# 1st available AZ
|
||||
availability_zone = "${data.aws_availability_zones.available.names[0]}"
|
||||
cidr_block = "10.0.255.0/24"
|
||||
map_public_ip_on_launch = true
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-vpn"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "pub_subnet_generic" {
|
||||
subnet_id = "${aws_subnet.pub_subnet_generic.id}"
|
||||
route_table_id = "${aws_route_table.pub_rt.id}"
|
||||
}
|
||||
|
||||
# public subnet route table
|
||||
resource "aws_route_table" "pub_rt" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
route {
|
||||
cidr_block = "0.0.0.0/0"
|
||||
gateway_id = "${aws_internet_gateway.igw.id}"
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-public"
|
||||
}
|
||||
}
|
||||
|
||||
# private subnets
|
||||
resource "aws_subnet" "priv_subnet" {
|
||||
count = "${var.subnet_count}"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
availability_zone = "${element(data.aws_availability_zones.available.names, count.index)}"
|
||||
cidr_block = "${cidrsubnet(var.vpc_cidr, 8, count.index + 100)}"
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-${count.index}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "priv_subnet" {
|
||||
count = "${var.subnet_count}"
|
||||
subnet_id = "${aws_subnet.priv_subnet.*.id[count.index]}"
|
||||
route_table_id = "${aws_route_table.priv_rt.id}"
|
||||
}
|
||||
|
||||
# private subnet route table
|
||||
resource "aws_route_table" "priv_rt" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
propagating_vgws = ["${aws_vpn_gateway.vpg.id}"]
|
||||
|
||||
route {
|
||||
cidr_block = "0.0.0.0/0"
|
||||
nat_gateway_id = "${aws_nat_gateway.natgw.id}"
|
||||
}
|
||||
|
||||
route {
|
||||
cidr_block = "${var.local_network_cidr}"
|
||||
gateway_id = "${aws_vpn_gateway.vpg.id}"
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-private"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
# placeholders for access_key / secret_key
|
||||
# should be fed through env var or variable file
|
||||
# https://www.terraform.io/docs/configuration/variables.html
|
||||
|
||||
variable vpc_name {
|
||||
description = "The name of the VPC to identify created resources."
|
||||
}
|
||||
|
||||
variable base_domain {
|
||||
default = "tectonic-ci.de"
|
||||
description = "The base domain for this cluster's FQDN"
|
||||
}
|
||||
|
||||
variable vpc_aws_region {
|
||||
description = "The target AWS region for the cluster"
|
||||
}
|
||||
|
||||
variable vpc_cidr {
|
||||
default = "10.0.0.0/16"
|
||||
description = "The CIDR range used for your entire VPC"
|
||||
}
|
||||
|
||||
variable subnet_count {
|
||||
default = 4
|
||||
description = "Number of private subnets to pre-create"
|
||||
}
|
||||
|
||||
variable local_network_cidr {
|
||||
default = "10.7.0.0/16"
|
||||
description = "IP range in the network your laptop is on (dosn't actually matter unless your instances need to connect to the local network your laptop is on)"
|
||||
}
|
||||
|
||||
variable ovpn_password {
|
||||
default = "PASSWORD"
|
||||
description = "password to use when connecting"
|
||||
}
|
||||
|
||||
output "ovpn_url" {
|
||||
value = "https://${aws_eip.ovpn_eip.public_ip}:443"
|
||||
}
|
||||
|
||||
output "base_domain" {
|
||||
value = "${var.base_domain}"
|
||||
}
|
||||
|
||||
output "private_zone_id" {
|
||||
value = "${aws_route53_zone.priv_zone.id}"
|
||||
}
|
||||
|
||||
output "vpc_id" {
|
||||
value = "${aws_vpc.vpc.id}"
|
||||
}
|
||||
|
||||
output "vpc_dns" {
|
||||
value = "${cidrhost(var.vpc_cidr, 2)}"
|
||||
}
|
||||
|
||||
output "subnets" {
|
||||
value = "${aws_subnet.priv_subnet.*.id}"
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
# For details see https://docs.openvpn.net/how-to-tutorialsguides/virtual-platforms/amazon-ec2-appliance-ami-quick-start-guide
|
||||
data "aws_ami" "openvpn_ami" {
|
||||
most_recent = true
|
||||
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["OpenVPN Access Server*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "architecture"
|
||||
values = ["x86_64"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "owner-id"
|
||||
values = ["679593333241"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_vpn_gateway" "vpg" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
# 1st available AZ
|
||||
availability_zone = "${data.aws_availability_zones.available.names[0]}"
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-vpg"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_instance" "ovpn" {
|
||||
# 1st available AZ
|
||||
availability_zone = "${data.aws_availability_zones.available.names[0]}"
|
||||
ami = "${data.aws_ami.openvpn_ami.image_id}"
|
||||
instance_type = "t2.micro"
|
||||
subnet_id = "${aws_subnet.pub_subnet_generic.id}"
|
||||
vpc_security_group_ids = ["${aws_security_group.vpn_sg.id}"]
|
||||
|
||||
user_data = <<EOF
|
||||
public_hostname=${aws_eip.ovpn_eip.public_ip}
|
||||
admin_user=openvpn
|
||||
admin_pw=${var.ovpn_password}
|
||||
reroute_gw=1
|
||||
reroute_dns=1
|
||||
EOF
|
||||
|
||||
depends_on = ["aws_eip.ovpn_eip"]
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-ovpn-server"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_eip" "ovpn_eip" {
|
||||
vpc = true
|
||||
}
|
||||
|
||||
resource "aws_eip_association" "vpn_eip_assoc" {
|
||||
instance_id = "${aws_instance.ovpn.id}"
|
||||
allocation_id = "${aws_eip.ovpn_eip.id}"
|
||||
}
|
||||
|
||||
resource "aws_security_group" "vpn_sg" {
|
||||
name = "ovpn-server-sg"
|
||||
description = "Allow all inbound traffic"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
ingress {
|
||||
from_port = 943
|
||||
to_port = 943
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 943
|
||||
to_port = 943
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
from_port = 1194
|
||||
to_port = 1194
|
||||
protocol = "udp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
|
||||
# all
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-ovpn-sg"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_customer_gateway" "customer_gateway" {
|
||||
bgp_asn = 65000
|
||||
ip_address = "${aws_eip.ovpn_eip.public_ip}"
|
||||
type = "ipsec.1"
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-customer-gateway"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_vpn_connection" "main" {
|
||||
vpn_gateway_id = "${aws_vpn_gateway.vpg.id}"
|
||||
customer_gateway_id = "${aws_customer_gateway.customer_gateway.id}"
|
||||
type = "ipsec.1"
|
||||
static_routes_only = true
|
||||
|
||||
tags {
|
||||
Name = "${var.vpc_name}-vpn-conn"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"tectonic_admin_email": "admin@example.com",
|
||||
"tectonic_admin_password": "password",
|
||||
"tectonic_aws_etcd_ec2_type": "t2.medium",
|
||||
"tectonic_aws_etcd_root_volume_size": 30,
|
||||
"tectonic_aws_etcd_root_volume_type": "gp2",
|
||||
"tectonic_aws_extra_tags": {
|
||||
"test_tag": "testing"
|
||||
},
|
||||
"tectonic_aws_master_custom_subnets": {
|
||||
"us-west-1a": "10.0.0.0/19",
|
||||
"us-west-1c": "10.0.32.0/19"
|
||||
},
|
||||
"tectonic_aws_master_ec2_type": "t2.medium",
|
||||
"tectonic_aws_master_root_volume_size": 30,
|
||||
"tectonic_aws_master_root_volume_type": "gp2",
|
||||
"tectonic_aws_private_endpoints": false,
|
||||
"tectonic_aws_region": "us-west-1",
|
||||
"tectonic_aws_ssh_key": "tectonic-jenkins",
|
||||
"tectonic_aws_vpc_cidr_block": "10.0.0.0/16",
|
||||
"tectonic_aws_worker_custom_subnets": {
|
||||
"us-west-1a": "10.0.64.0/19",
|
||||
"us-west-1c": "10.0.96.0/19"
|
||||
},
|
||||
"tectonic_aws_worker_ec2_type": "t2.medium",
|
||||
"tectonic_aws_worker_root_volume_size": 30,
|
||||
"tectonic_aws_worker_root_volume_type": "gp2",
|
||||
"tectonic_base_domain": "tectonic.dev.coreos.systems",
|
||||
"tectonic_cluster_cidr": "10.2.0.0/16",
|
||||
"tectonic_cluster_name": "test",
|
||||
"tectonic_dns_name": "test",
|
||||
"tectonic_etcd_count": 3,
|
||||
"tectonic_kube_apiserver_service_ip": "10.3.0.1",
|
||||
"tectonic_kube_dns_service_ip": "10.3.0.10",
|
||||
"tectonic_kube_etcd_service_ip": "10.3.0.15",
|
||||
"tectonic_license_path": "./license.txt",
|
||||
"tectonic_master_count": 3,
|
||||
"tectonic_pull_secret_path": "./pull_secret.json",
|
||||
"tectonic_service_cidr": "10.3.0.0/16",
|
||||
"tectonic_worker_count": 3
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"tectonic_admin_email": "admin@example.com",
|
||||
"tectonic_admin_password": "password",
|
||||
"tectonic_base_domain": "unused",
|
||||
"tectonic_cluster_cidr": "10.2.0.0/16",
|
||||
"tectonic_cluster_name": "my-cluster",
|
||||
"tectonic_container_linux_version": "1353.8.0",
|
||||
"tectonic_dns_name": "",
|
||||
"tectonic_kube_apiserver_service_ip": "10.3.0.1",
|
||||
"tectonic_kube_dns_service_ip": "10.3.0.10",
|
||||
"tectonic_kube_etcd_service_ip": "10.3.0.15",
|
||||
"tectonic_license_path": "./license.txt",
|
||||
"tectonic_metal_controller_domain": "cluster.example.com",
|
||||
"tectonic_metal_controller_domains": [
|
||||
"node1.example.com"
|
||||
],
|
||||
"tectonic_metal_controller_macs": [
|
||||
"52:54:00:a1:9c:ae"
|
||||
],
|
||||
"tectonic_metal_controller_names": [
|
||||
"node1"
|
||||
],
|
||||
"tectonic_metal_ingress_domain": "tectonic.example.com",
|
||||
"tectonic_metal_matchbox_ca": "-----BEGIN CERTIFICATE-----\nMIIFDTCCAvWgAwIBAgIJAIuXq10k2OFlMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\nBAMMB2Zha2UtY2EwHhcNMTcwMjAxMjIxMzI0WhcNMjcwMTMwMjIxMzI0WjASMRAw\nDgYDVQQDDAdmYWtlLWNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA\nzzHsB56F6oZjsVBKzfpicsG+mVHQ/QzA4jqRCbQ8Zr12NtUZKnPUVwDoFf4WTfmy\nZ0u8Uv+6/B/8un3LGsIaJEugPfRboc2oZKJcqfMJSFfLb/wkmT0D/1HJR60ml/M5\nwpHeh4vQ7BhktNsK90EjdlLvr1GDfevXArnye5ksEInOSX9nXVsGPrm0AGSffhmY\nuUAjY8f9IspJa1j4vL6NI89GWO4jqME+SUnuI4SYIkuQJoSElofAIX2b5Tk3dFya\nVKmAq2L89teCMYsciPbFa/Z2HvDNZ7pC17Ow7zr1f+V5BU18h3cLk610YNPcEBw0\nf94+mePsmMSMjUM0f+NMFyDERF+pys60/3qqVWrJe/FkJM6NDCyWXXXAfTxIwLq0\nCVrlWALdTc+RMAPI2sxAdUp4BqAuek4SjIg3FuoJrBs3EAUPfybclJ7g3HJwyXM2\n3WIe10BnSk+rGzd4KMVbYw5/nM8Nc/Y20R2an/vVZn6xTxs9o6hhEHF7d5iws6Bi\n7/jv+jdZhLG8b3sG6Tj7a7YdvKWqH/mSPFlc/sevYOjR7NKYRMwGnl0d9qf+Xe5V\nxyH1llIXPs6+y1B4tRyL/tulyeVqi25+I4QVAYypxWU8CPyw7tsSdOsSTbeGTmXj\nehelY/BCjAqAcexL7oRV7dy7VZ1Ezg6zQRwMt0Tar90CAwEAAaNmMGQwHQYDVR0O\nBBYEFNGPoXTjJnHjG2zMpjSg/9vNO/trMB8GA1UdIwQYMBaAFNGPoXTjJnHjG2zM\npjSg/9vNO/trMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMA0G\nCSqGSIb3DQEBCwUAA4ICAQC9V/0iiEZYHz7xbezHpeGHwmecH5oylEvAeCcN10gx\nHFvUN+XMyBaPqN7iRtx/rSqyp2iN2AK1Cdn1viOSRc09lwPiuj9V4diSDyPwJWxd\n60gqd5E9F9gQXlenWoIdm7kW8Lo8HLfx8ItYKGpE51JUctTmGY5WURRmBlVKr1LA\nhbVsAWBaGQfPyW1CrFcxxc5mCABxWOxjRjLw8A8c5IXD0Q5C5pRd0BckBHKTdl40\nowm893oPEQcu/1C432T4vIddVh1Ktq1pd7O/9BPYOaPryzf7076xSwZ0bSuBUGRq\nVd3STfu5QRqpMv4dIrhqRofmIUzjOHLRX8Lx2pzgYcMgMQ8O+jM+ETrYD6rsDoLQ\nuiVSWZK0YFndKzNTA04u57arRumWKqqfS0kkDFayumyv6KaDS6YZdsqSRmaiLAOG\nF6jchpUtkDhDY0v/Y7jESUneT0hRnqNMPAKJMNhE4hS+1qkcP/ikQQgZl/OWma1z\nHUyBGT4OGP2T3JIfq12Z4vC5FGVD4aD/frTvPMlifV3i8lKlYZs271JPXUo6ASIA\nZSBpV5QilOlE25Q5Lcw0yWmN4KwxqBL9bJ5W9D1I0qhWxaMF78m+8vLIFv+dAylE\nOd27a+1We/P5ey7WRlwCfuEcFV7nYS/qMykYdQ9fxHSPgTPlrGrSwKstaaIIqOkE\nkA==\n-----END CERTIFICATE-----\n",
|
||||
"tectonic_metal_matchbox_client_cert": "-----BEGIN CERTIFICATE-----\nMIIEYDCCAkigAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHZmFr\nZS1jYTAeFw0xNzAyMDEyMjEzMjVaFw0xODAyMDEyMjEzMjVaMBYxFDASBgNVBAMM\nC2Zha2UtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr8S7\nx/tAS6W+aRW3X833OvNfxXjUJAiRkUV85Raln7tqVcTG/9iyRhWgNpUn/WU1/3qV\nobto4ZCURIwoQh0kWk8io1lafZJ+S6Znm3+0TKo7u6QMavolJyetsOQkT/bIoZ73\n09fhk4Vu9GILjtZtxV7GDb4WqR9R7z77nYTdHMio/BQVk+Xg6rkOsMRyoR+B9JHG\nn9mvXLZSi8Q+3ABtsN6flPt7mTkhFFFvTgWxtzgVbeORT/uFxIV/IMjtGseUIzvF\nGUQP6KCyCJb3Kp4rxSxIbi35mFqEWXjB7BVT/0pjx1mc5tSvGuFl7G4N/MmGe3Zq\nZCF4FalpiPGAInKrWQIDAQABo4G7MIG4MAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEB\nBAQDAgeAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBDbGllbnQg\nQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNZOj+0OOvhOFEtGGriZrPVCSzc3MB8GA1Ud\nIwQYMBaAFNGPoXTjJnHjG2zMpjSg/9vNO/trMA4GA1UdDwEB/wQEAwIF4DATBgNV\nHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAgEAiiGHlmPI6RlJQq7/\nz/1i0vFArDbnc2mwBf3pqrDPyqx1EBx7V3Tsm38TNMZyHaz0IyPUDvRPn10UYXui\n2ZGseauwU/PmvFNofxVbG0Dc55lOoxl31520K0h9cWxVHcYzUxPndQ1pltYkXiMm\n/596LHkJ+unMJszDVhAIOmc0PgECtGH1VG6EoTTFlMu7VJekKInkYNow4Q6cAVcr\n11F4meOs0DMZgzfeUjSnsKG7KsLHfr5bLw6FEEzobgtI2sXVMOJi+ypd3zTY+ACq\noRt6wkRFCUoEgap7SG6B2TwHPGe15VIFZJtcnOZqHdrnfJLVROPnA4dYhJVJj1v1\n9JFH/T6EIi6nIqnrlX+10zaatpzq2+AFX8LiWpr7C7S99LgH3cnFdssfmlqoG82t\n3BshYpDrIw1f72zy8+RCkK52OdjNpDoVwubwz6i8jldzoENqmsioyetyaVfe9GGH\nUdEPrUZ4BHLeGPjHclOPVEhjVBZuofQ/GgM2gmCUdn5tcVLjnIeLAv/sQXwkMxIe\n4m9QcPrxVAKOlDr9LhB0mVPr2kfc4yI/wYWEe+CniwcuvxJiOmjsyrENxfaFY30r\nQspTSDVt8hVfVISzpuEchtLVjuRO/ESpmeOF1rRTc1qL/CjetmidkedDm64EZjyK\njyXQv9IZPMTwOndF6AVLH7l1F0E=\n-----END CERTIFICATE-----\n",
|
||||
"tectonic_metal_matchbox_client_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAr8S7x/tAS6W+aRW3X833OvNfxXjUJAiRkUV85Raln7tqVcTG\n/9iyRhWgNpUn/WU1/3qVobto4ZCURIwoQh0kWk8io1lafZJ+S6Znm3+0TKo7u6QM\navolJyetsOQkT/bIoZ7309fhk4Vu9GILjtZtxV7GDb4WqR9R7z77nYTdHMio/BQV\nk+Xg6rkOsMRyoR+B9JHGn9mvXLZSi8Q+3ABtsN6flPt7mTkhFFFvTgWxtzgVbeOR\nT/uFxIV/IMjtGseUIzvFGUQP6KCyCJb3Kp4rxSxIbi35mFqEWXjB7BVT/0pjx1mc\n5tSvGuFl7G4N/MmGe3ZqZCF4FalpiPGAInKrWQIDAQABAoIBAQCR/OQ+0JdxfWNu\nYqQhBbA/nV7BZH9GwnstXrrCiBHeXsqOHFdwruo7PcEJNM+3LnYwEP/xCfityOjt\nGkBh0VSdUbciV5fKTn9pk/ff9qypNIdSbYoG3Gc5Y0JndsYWSJIRczjCEj+AyMYE\nYt7Yr48S7ImxZl3p8GKcRQK1rWH9geg4cyCPisbaDSfjJbYh5yLk/2wsxGBRM3gg\nCyJEbkJ/v107a1iThTGBgEgnFPP+FqZ2jlnfhBPVzuYggYyiMJuNtgDl7Vi7NLBe\n2ueqq1UAT9LCpZNLJ8eYiDuyNHZtA7a2r3O/jTR4cvQy1xEjD3h4Es7olkAf/Lzu\n6wuggbllAoGBANcqZyJtVxkGwHV9CWTWniTT7BNQ2ehYErkNKggMXl2AzOqEKzqn\nIDRoBhiJKeAphdw/ccvqUEm9bUJD2QLpTJuMmUBkOwqMhATBXFrFCBX4PzGHYnC8\n6hEXjoUE6XhKdJEOgXTqrt31HDgj13GwAp/2DnsscFkC9co5+IW68sUjAoGBANEg\nQvZYdI4Me6JxLXotyirpo57xjocvlo+uffws/YwBH8nK/op6am69zzMMOgUYA5Li\n00WzfEXoyO+BdcbH28xYdBZT0CTkGlPM8IHuH+d/AwnEurxUElWZRRXSz6g17siM\nKjBodqI8h+jQiQJuJ/zBJbOm3bUbpIt1Z+ROjstTAoGAWdAdVMWHQa8Lzv7uWOUt\nBfpf5IAvNUjuJ8hS7yEakrUc1BdvZAA29Skmwj8e967dbV4eRhv8f4tOfAaOIyT3\nEUbTAYnVC0Y0JTgBMPJluaXx2t7EPILewVuv5d5zBf8uQQ5pA0Ci1YtmyBhN6eqq\nbdLroIagLseJiWxBTLEIfTkCgYEAjikXPC2fdhzoQuIbHy5Xe1p+PwNId3+TIzNk\nM3RGG9F70YqsBGj5RzTC0JnkKyhK7aRCKOS9eyymw6HG9Y1RTpVmvPLW0O07NHJh\noIHGsHD4GMDijDm+iO/7Nb2sKlYXb79Qwr2Qv/LUFSEFsmA90KVgQsMRfhc/gQob\nyOjaSz8CgYEAwr3aYp1CkKBXeUTNioLbyymhA4RqGPH/69F1NQ7froLXb152SzOV\njWcrt4ogRacgHb8thuTedrjUiJJLoWhQ3KqzSA2pI3tTLIxrJePiMMpt1Xb2z9l6\nPikk0rvNVB/vrPeVjAdGY9TJC/vpz3om92DRDmUifu8rCFxIHE0GrQ0=\n-----END RSA PRIVATE KEY-----\n",
|
||||
"tectonic_metal_matchbox_http_url": "http://matchbox.example.com:8080",
|
||||
"tectonic_metal_matchbox_rpc_endpoint": "matchbox.example.com:8081",
|
||||
"tectonic_metal_worker_domains": [
|
||||
"node2.example.com",
|
||||
"node3.example.com"
|
||||
],
|
||||
"tectonic_metal_worker_macs": [
|
||||
"52:54:00:b2:2f:86",
|
||||
"52:54:00:c3:61:77"
|
||||
],
|
||||
"tectonic_metal_worker_names": [
|
||||
"node2",
|
||||
"node3"
|
||||
],
|
||||
"tectonic_pull_secret_path": "./pull_secret.json",
|
||||
"tectonic_service_cidr": "10.3.0.0/16",
|
||||
"tectonic_ssh_authorized_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCt3BebCHqnSsgpLjo4kVvyfY/z2BS8t27r/7du+O2pb4xYkr7n+KFpbOz523vMTpQ+o1jY4u4TgexglyT9nqasWgLOvo1qjD1agHme8LlTPQSk07rXqOB85Uq5p7ig2zoOejF6qXhcc3n1c7+HkxHrgpBENjLVHOBpzPBIAHkAGaZcl07OCqbsG5yxqEmSGiAlh/IiUVOZgdDMaGjCRFy0wk0mQaGD66DmnFc1H5CzcPjsxr0qO65e7lTGsE930KkO1Vc+RHCVwvhdXs+c2NhJ2/3740Kpes9n1/YullaWZUzlCPDXtRuy6JRbFbvy39JUgHWGWzB3d+3f8oJ/N4qZ cardno:000603633110"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
locals {
|
||||
ignition_etcd_keys = ["ignition_etcd_0.json", "ignition_etcd_1.json", "ignition_etcd_2.json"]
|
||||
}
|
||||
|
||||
data "ignition_config" "tnc" {
|
||||
count = "${var.instance_count}"
|
||||
|
||||
append {
|
||||
source = "${format("http://${var.cluster_name}-tnc.${var.base_domain}/config/etcd?etcd_index=%d", count.index)}"
|
||||
|
||||
# TODO: add verification
|
||||
}
|
||||
|
||||
# Used for loading certificates
|
||||
append {
|
||||
source = "${format("s3://%s/%s", var.s3_bucket, local.ignition_etcd_keys[count.index])}"
|
||||
|
||||
# TODO: add verification
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
data "ignition_config" "etcd" {
|
||||
count = "${length(var.external_endpoints) == 0 ? var.instance_count : 0}"
|
||||
|
||||
systemd = [
|
||||
"${data.ignition_systemd_unit.locksmithd.*.id[count.index]}",
|
||||
"${var.ign_etcd_dropin_id_list[count.index]}",
|
||||
]
|
||||
|
||||
files = ["${compact(list(
|
||||
var.ign_profile_env_id,
|
||||
var.ign_systemd_default_env_id,
|
||||
))}",
|
||||
"${var.ign_etcd_crt_id_list}",
|
||||
"${var.ign_ntp_dropin_id}",
|
||||
]
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "locksmithd" {
|
||||
count = "${length(var.external_endpoints) == 0 ? var.instance_count : 0}"
|
||||
|
||||
name = "locksmithd.service"
|
||||
enabled = true
|
||||
|
||||
dropin = [
|
||||
{
|
||||
name = "40-etcd-lock.conf"
|
||||
|
||||
content = <<EOF
|
||||
[Service]
|
||||
Environment=REBOOT_STRATEGY=etcd-lock
|
||||
${var.tls_enabled ? "Environment=\"LOCKSMITHD_ETCD_CAFILE=/etc/ssl/etcd/ca.crt\"" : ""}
|
||||
${var.tls_enabled ? "Environment=\"LOCKSMITHD_ETCD_KEYFILE=/etc/ssl/etcd/client.key\"" : ""}
|
||||
${var.tls_enabled ? "Environment=\"LOCKSMITHD_ETCD_CERTFILE=/etc/ssl/etcd/client.crt\"" : ""}
|
||||
Environment="LOCKSMITHD_ENDPOINT=${var.tls_enabled ? "https" : "http"}://${var.cluster_name}-etcd-${count.index}.${var.base_domain}:2379"
|
||||
EOF
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
resource "aws_s3_bucket_object" "ignition_etcd" {
|
||||
count = "${length(var.external_endpoints) == 0 ? var.instance_count : 0}"
|
||||
|
||||
bucket = "${var.s3_bucket}"
|
||||
key = "ignition_etcd_${count.index}.json"
|
||||
content = "${data.ignition_config.etcd.*.rendered[count.index]}"
|
||||
acl = "private"
|
||||
|
||||
server_side_encryption = "AES256"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-ignition-etcd-${count.index}",
|
||||
"KubernetesCluster", "${var.cluster_name}",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
data "ignition_config" "s3" {
|
||||
count = "${length(var.external_endpoints) == 0 ? var.instance_count : 0}"
|
||||
|
||||
replace {
|
||||
source = "${format("s3://%s/%s", var.s3_bucket, aws_s3_bucket_object.ignition_etcd.*.key[count.index])}"
|
||||
verification = "sha512-${sha512(data.ignition_config.etcd.*.rendered[count.index])}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
locals {
|
||||
ami_owner = "595879546273"
|
||||
arn = "aws"
|
||||
}
|
||||
|
||||
data "aws_ami" "coreos_ami" {
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["CoreOS-${var.container_linux_channel}-${var.container_linux_version}-*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "architecture"
|
||||
values = ["x86_64"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "owner-id"
|
||||
values = ["${local.ami_owner}"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "etcd" {
|
||||
name = "${var.cluster_name}-etcd-profile"
|
||||
|
||||
role = "${var.etcd_iam_role == "" ?
|
||||
join("|", aws_iam_role.etcd_role.*.name) :
|
||||
join("|", data.aws_iam_role.etcd_role.*.name)
|
||||
}"
|
||||
}
|
||||
|
||||
data "aws_iam_role" "etcd_role" {
|
||||
count = "${var.etcd_iam_role == "" ? 0 : 1}"
|
||||
name = "${var.etcd_iam_role}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "etcd_role" {
|
||||
count = "${var.etcd_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-role"
|
||||
path = "/"
|
||||
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ec2.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow",
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "etcd" {
|
||||
count = "${var.etcd_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}_etcd_policy"
|
||||
role = "${aws_iam_role.etcd_role.id}"
|
||||
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:Describe*",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:AttachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:DetachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"s3:GetObject"
|
||||
],
|
||||
"Resource": "arn:${local.arn}:s3:::*",
|
||||
"Effect": "Allow"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_instance" "etcd_node" {
|
||||
count = "${var.instance_count}"
|
||||
ami = "${coalesce(var.ec2_ami, data.aws_ami.coreos_ami.image_id)}"
|
||||
|
||||
iam_instance_profile = "${aws_iam_instance_profile.etcd.name}"
|
||||
instance_type = "${var.ec2_type}"
|
||||
key_name = "${var.ssh_key}"
|
||||
subnet_id = "${element(var.subnets, count.index)}"
|
||||
user_data = "${data.ignition_config.tnc.*.rendered[count.index]}"
|
||||
vpc_security_group_ids = ["${var.sg_ids}"]
|
||||
|
||||
lifecycle {
|
||||
# Ignore changes in the AMI which force recreation of the resource. This
|
||||
# avoids accidental deletion of nodes whenever a new CoreOS Release comes
|
||||
# out.
|
||||
ignore_changes = ["ami"]
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-etcd-${count.index}",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
|
||||
root_block_device {
|
||||
volume_type = "${var.root_volume_type}"
|
||||
volume_size = "${var.root_volume_size}"
|
||||
iops = "${var.root_volume_type == "io1" ? var.root_volume_iops : var.root_volume_type == "gp2" ? min(10000, max(100, 3 * var.root_volume_size)) : 0}"
|
||||
}
|
||||
|
||||
volume_tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-etcd-${count.index}-vol",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
locals {
|
||||
ami_owner = "595879546273"
|
||||
arn = "aws"
|
||||
}
|
||||
|
||||
data "aws_ami" "coreos_ami" {
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["CoreOS-${var.container_linux_channel}-${var.container_linux_version}-*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "architecture"
|
||||
values = ["x86_64"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "owner-id"
|
||||
values = ["${local.ami_owner}"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "etcd" {
|
||||
count = "${length(var.external_endpoints) == 0 ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-profile"
|
||||
|
||||
role = "${var.etcd_iam_role == "" ?
|
||||
join("|", aws_iam_role.etcd_role.*.name) :
|
||||
join("|", data.aws_iam_role.etcd_role.*.name)
|
||||
}"
|
||||
}
|
||||
|
||||
data "aws_iam_role" "etcd_role" {
|
||||
count = "${var.etcd_iam_role == "" ? 0 : 1}"
|
||||
name = "${var.etcd_iam_role}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "etcd_role" {
|
||||
count = "${length(var.external_endpoints) == 0 && var.etcd_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-role"
|
||||
path = "/"
|
||||
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ec2.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow",
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "etcd" {
|
||||
count = "${var.etcd_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}_etcd_policy"
|
||||
role = "${aws_iam_role.etcd_role.id}"
|
||||
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:Describe*",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:AttachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:DetachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Action": [
|
||||
"ecr:DescribeRepositories",
|
||||
"ecr:ListImages",
|
||||
"ecr:BatchGetImage"
|
||||
],
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"s3:GetObject"
|
||||
],
|
||||
"Resource": "arn:${local.arn}:s3:::*",
|
||||
"Effect": "Allow"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_instance" "etcd_node" {
|
||||
count = "${length(var.external_endpoints) == 0 ? var.instance_count : 0}"
|
||||
ami = "${coalesce(var.ec2_ami, data.aws_ami.coreos_ami.image_id)}"
|
||||
|
||||
iam_instance_profile = "${aws_iam_instance_profile.etcd.name}"
|
||||
instance_type = "${var.ec2_type}"
|
||||
key_name = "${var.ssh_key}"
|
||||
subnet_id = "${element(var.subnets, count.index)}"
|
||||
user_data = "${data.ignition_config.s3.*.rendered[count.index]}"
|
||||
vpc_security_group_ids = ["${var.sg_ids}"]
|
||||
|
||||
lifecycle {
|
||||
# Ignore changes in the AMI which force recreation of the resource. This
|
||||
# avoids accidental deletion of nodes whenever a new CoreOS Release comes
|
||||
# out.
|
||||
ignore_changes = ["ami"]
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-etcd-${count.index}",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
|
||||
root_block_device {
|
||||
volume_type = "${var.root_volume_type}"
|
||||
volume_size = "${var.root_volume_size}"
|
||||
iops = "${var.root_volume_type == "io1" ? var.root_volume_iops : var.root_volume_type == "gp2" ? min(10000, max(100, 3 * var.root_volume_size)) : 0}"
|
||||
}
|
||||
|
||||
volume_tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-etcd-${count.index}-vol",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
output "ip_addresses" {
|
||||
value = "${aws_instance.etcd_node.*.private_ip}"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
output "ip_addresses" {
|
||||
value = "${aws_instance.etcd_node.*.private_ip}"
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
variable "base_domain" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_channel" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_version" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "instance_count" {
|
||||
default = "3"
|
||||
}
|
||||
|
||||
variable "ssh_key" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "subnets" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "container_image" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ec2_type" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ec2_ami" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created resources."
|
||||
type = "map"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "root_volume_type" {
|
||||
type = "string"
|
||||
description = "The type of volume for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_size" {
|
||||
type = "string"
|
||||
description = "The size of the volume in gigabytes for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_iops" {
|
||||
type = "string"
|
||||
default = "100"
|
||||
description = "The amount of provisioned IOPS for the root block device."
|
||||
}
|
||||
|
||||
variable "sg_ids" {
|
||||
type = "list"
|
||||
description = "The security group IDs to be applied."
|
||||
}
|
||||
|
||||
variable "s3_bucket" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "etcd_iam_role" {
|
||||
type = "string"
|
||||
default = ""
|
||||
description = "IAM role to use for the instance profiles of etcd nodes."
|
||||
}
|
||||
|
||||
variable "dns_server_ip" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
variable "base_domain" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_channel" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_version" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "instance_count" {
|
||||
default = "3"
|
||||
}
|
||||
|
||||
variable "ssh_key" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "subnets" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "external_endpoints" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "container_image" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ec2_type" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ec2_ami" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created resources."
|
||||
type = "map"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "root_volume_type" {
|
||||
type = "string"
|
||||
description = "The type of volume for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_size" {
|
||||
type = "string"
|
||||
description = "The size of the volume in gigabytes for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_iops" {
|
||||
type = "string"
|
||||
default = "100"
|
||||
description = "The amount of provisioned IOPS for the root block device."
|
||||
}
|
||||
|
||||
variable "sg_ids" {
|
||||
type = "list"
|
||||
description = "The security group IDs to be applied."
|
||||
}
|
||||
|
||||
variable "tls_enabled" {
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "ign_etcd_dropin_id_list" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "s3_bucket" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_etcd_crt_id_list" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "etcd_iam_role" {
|
||||
type = "string"
|
||||
default = ""
|
||||
description = "IAM role to use for the instance profiles of etcd nodes."
|
||||
}
|
||||
|
||||
variable "ign_profile_env_id" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "ign_systemd_default_env_id" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "ign_ntp_dropin_id" {
|
||||
type = "string"
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
data "ignition_config" "main" {
|
||||
files = ["${compact(list(
|
||||
data.ignition_file.detect_master.id,
|
||||
data.ignition_file.init_assets.id,
|
||||
data.ignition_file.rm_assets.id,
|
||||
var.ign_installer_kubelet_env_id,
|
||||
var.ign_installer_runtime_mappings_id,
|
||||
var.ign_max_user_watches_id,
|
||||
var.ign_nfs_config_id,
|
||||
var.ign_ntp_dropin_id,
|
||||
var.ign_profile_env_id,
|
||||
var.ign_s3_puller_id,
|
||||
var.ign_systemd_default_env_id,
|
||||
))}",
|
||||
"${var.ign_ca_cert_id_list}",
|
||||
]
|
||||
|
||||
systemd = ["${compact(list(
|
||||
var.ign_bootkube_path_unit_id,
|
||||
var.ign_bootkube_service_id,
|
||||
var.ign_docker_dropin_id,
|
||||
var.ign_init_assets_service_id,
|
||||
var.ign_iscsi_service_id,
|
||||
var.ign_k8s_node_bootstrap_service_id,
|
||||
var.ign_kubelet_service_id,
|
||||
var.ign_locksmithd_service_id,
|
||||
var.ign_rm_assets_path_unit_id,
|
||||
var.ign_rm_assets_service_id,
|
||||
var.ign_tectonic_path_unit_id,
|
||||
var.ign_tectonic_service_id,
|
||||
var.ign_update_ca_certificates_dropin_id,
|
||||
))}"]
|
||||
}
|
||||
|
||||
data "template_file" "detect_master" {
|
||||
template = "${file("${path.module}/resources/detect-master.sh")}"
|
||||
|
||||
vars {
|
||||
load_balancer_name = "${format("%s-%s", var.cluster_name, var.private_endpoints ? "int" : "ext")}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_file" "detect_master" {
|
||||
filesystem = "root"
|
||||
path = "/opt/detect-master.sh"
|
||||
mode = 0755
|
||||
|
||||
content {
|
||||
content = "${data.template_file.detect_master.rendered}"
|
||||
}
|
||||
}
|
||||
|
||||
data "template_file" "init_assets" {
|
||||
template = "${file("${path.module}/resources/init-assets.sh")}"
|
||||
|
||||
vars {
|
||||
assets_s3_location = "${var.assets_s3_location}"
|
||||
awscli_image = "${var.container_images["awscli"]}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_file" "init_assets" {
|
||||
filesystem = "root"
|
||||
path = "/opt/init-assets.sh"
|
||||
mode = 0755
|
||||
|
||||
content {
|
||||
content = "${data.template_file.init_assets.rendered}"
|
||||
}
|
||||
}
|
||||
|
||||
data "template_file" "rm_assets" {
|
||||
template = "${file("${path.module}/resources/rm-assets.sh")}"
|
||||
|
||||
vars {
|
||||
assets_s3_location = "${var.assets_s3_location}"
|
||||
awscli_image = "${var.container_images["awscli"]}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_file" "rm_assets" {
|
||||
filesystem = "root"
|
||||
path = "/opt/rm-assets.sh"
|
||||
mode = 0755
|
||||
|
||||
content {
|
||||
content = "${data.template_file.rm_assets.rendered}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
resource "aws_s3_bucket_object" "ignition_master" {
|
||||
bucket = "${var.s3_bucket}"
|
||||
key = "ignition_master.json"
|
||||
content = "${data.ignition_config.main.rendered}"
|
||||
acl = "private"
|
||||
|
||||
server_side_encryption = "AES256"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-ignition-master",
|
||||
"KubernetesCluster", "${var.cluster_name}",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
data "ignition_config" "s3" {
|
||||
replace {
|
||||
source = "${format("s3://%s/%s", var.s3_bucket, aws_s3_bucket_object.ignition_master.key)}"
|
||||
verification = "sha512-${sha512(data.ignition_config.main.rendered)}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
locals {
|
||||
ami_owner = "595879546273"
|
||||
arn = "aws"
|
||||
}
|
||||
|
||||
data "aws_ami" "coreos_ami" {
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["CoreOS-${var.container_linux_channel}-${var.container_linux_version}-*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "architecture"
|
||||
values = ["x86_64"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "owner-id"
|
||||
values = ["${local.ami_owner}"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_autoscaling_group" "masters" {
|
||||
name = "${var.cluster_name}-masters"
|
||||
desired_capacity = "${var.instance_count}"
|
||||
max_size = "${var.instance_count * 3}"
|
||||
min_size = "${var.instance_count}"
|
||||
launch_configuration = "${aws_launch_configuration.master_conf.id}"
|
||||
vpc_zone_identifier = ["${var.subnet_ids}"]
|
||||
|
||||
load_balancers = ["${var.aws_lbs}"]
|
||||
|
||||
tags = [
|
||||
{
|
||||
key = "Name"
|
||||
value = "${var.cluster_name}-master"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
{
|
||||
key = "kubernetes.io/cluster/${var.cluster_name}"
|
||||
value = "owned"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
{
|
||||
key = "tectonicClusterID"
|
||||
value = "${var.cluster_id}"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
"${var.autoscaling_group_extra_tags}",
|
||||
]
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_launch_configuration" "master_conf" {
|
||||
instance_type = "${var.ec2_type}"
|
||||
image_id = "${coalesce(var.ec2_ami, data.aws_ami.coreos_ami.image_id)}"
|
||||
name_prefix = "${var.cluster_name}-master-"
|
||||
key_name = "${var.ssh_key}"
|
||||
security_groups = ["${var.master_sg_ids}"]
|
||||
iam_instance_profile = "${aws_iam_instance_profile.master_profile.arn}"
|
||||
associate_public_ip_address = "${var.public_endpoints}"
|
||||
user_data = "${var.user_data_ign}"
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
|
||||
# Ignore changes in the AMI which force recreation of the resource. This
|
||||
# avoids accidental deletion of nodes whenever a new CoreOS Release comes
|
||||
# out.
|
||||
ignore_changes = ["image_id"]
|
||||
}
|
||||
|
||||
root_block_device {
|
||||
volume_type = "${var.root_volume_type}"
|
||||
volume_size = "${var.root_volume_size}"
|
||||
iops = "${var.root_volume_type == "io1" ? var.root_volume_iops : 0}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "master_profile" {
|
||||
name = "${var.cluster_name}-master-profile"
|
||||
|
||||
role = "${var.master_iam_role == "" ?
|
||||
join("|", aws_iam_role.master_role.*.name) :
|
||||
join("|", data.aws_iam_role.master_role.*.name)
|
||||
}"
|
||||
}
|
||||
|
||||
data "aws_iam_role" "master_role" {
|
||||
count = "${var.master_iam_role == "" ? 0 : 1}"
|
||||
name = "${var.master_iam_role}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "master_role" {
|
||||
count = "${var.master_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-role"
|
||||
path = "/"
|
||||
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ec2.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow",
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "master_policy" {
|
||||
count = "${var.master_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}_master_policy"
|
||||
role = "${aws_iam_role.master_role.id}"
|
||||
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "ec2:*",
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action": "elasticloadbalancing:*",
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"s3:GetObject",
|
||||
"s3:HeadObject",
|
||||
"s3:ListBucket",
|
||||
"s3:PutObject"
|
||||
],
|
||||
"Resource": "arn:${local.arn}:s3:::*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"autoscaling:DescribeAutoScalingGroups",
|
||||
"autoscaling:DescribeAutoScalingInstances"
|
||||
],
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
locals {
|
||||
ami_owner = "595879546273"
|
||||
arn = "aws"
|
||||
}
|
||||
|
||||
data "aws_ami" "coreos_ami" {
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["CoreOS-${var.container_linux_channel}-${var.container_linux_version}-*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "architecture"
|
||||
values = ["x86_64"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "owner-id"
|
||||
values = ["${local.ami_owner}"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_autoscaling_group" "masters" {
|
||||
name = "${var.cluster_name}-masters"
|
||||
desired_capacity = "${var.instance_count}"
|
||||
max_size = "${var.instance_count * 3}"
|
||||
min_size = "${var.instance_count}"
|
||||
launch_configuration = "${aws_launch_configuration.master_conf.id}"
|
||||
vpc_zone_identifier = ["${var.subnet_ids}"]
|
||||
|
||||
load_balancers = ["${var.aws_lbs}"]
|
||||
|
||||
tags = [
|
||||
{
|
||||
key = "Name"
|
||||
value = "${var.cluster_name}-master"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
{
|
||||
key = "kubernetes.io/cluster/${var.cluster_name}"
|
||||
value = "owned"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
{
|
||||
key = "tectonicClusterID"
|
||||
value = "${var.cluster_id}"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
"${var.autoscaling_group_extra_tags}",
|
||||
]
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_launch_configuration" "master_conf" {
|
||||
instance_type = "${var.ec2_type}"
|
||||
image_id = "${coalesce(var.ec2_ami, data.aws_ami.coreos_ami.image_id)}"
|
||||
name_prefix = "${var.cluster_name}-master-"
|
||||
key_name = "${var.ssh_key}"
|
||||
security_groups = ["${var.master_sg_ids}"]
|
||||
iam_instance_profile = "${aws_iam_instance_profile.master_profile.arn}"
|
||||
associate_public_ip_address = "${var.public_endpoints}"
|
||||
user_data = "${data.ignition_config.s3.rendered}"
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
|
||||
# Ignore changes in the AMI which force recreation of the resource. This
|
||||
# avoids accidental deletion of nodes whenever a new CoreOS Release comes
|
||||
# out.
|
||||
ignore_changes = ["image_id"]
|
||||
}
|
||||
|
||||
root_block_device {
|
||||
volume_type = "${var.root_volume_type}"
|
||||
volume_size = "${var.root_volume_size}"
|
||||
iops = "${var.root_volume_type == "io1" ? var.root_volume_iops : 0}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "master_profile" {
|
||||
name = "${var.cluster_name}-master-profile"
|
||||
|
||||
role = "${var.master_iam_role == "" ?
|
||||
join("|", aws_iam_role.master_role.*.name) :
|
||||
join("|", data.aws_iam_role.master_role.*.name)
|
||||
}"
|
||||
}
|
||||
|
||||
data "aws_iam_role" "master_role" {
|
||||
count = "${var.master_iam_role == "" ? 0 : 1}"
|
||||
name = "${var.master_iam_role}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "master_role" {
|
||||
count = "${var.master_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-role"
|
||||
path = "/"
|
||||
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ec2.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow",
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "master_policy" {
|
||||
count = "${var.master_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}_master_policy"
|
||||
role = "${aws_iam_role.master_role.id}"
|
||||
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "ec2:*",
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action": "elasticloadbalancing:*",
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"s3:GetObject",
|
||||
"s3:HeadObject",
|
||||
"s3:ListBucket",
|
||||
"s3:PutObject"
|
||||
],
|
||||
"Resource": "arn:${local.arn}:s3:::*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"autoscaling:DescribeAutoScalingGroups",
|
||||
"autoscaling:DescribeAutoScalingInstances"
|
||||
],
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
variable "autoscaling_group_extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created autoscaling group resources."
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "base_domain" {
|
||||
type = "string"
|
||||
description = "Domain on which the ELB records will be created"
|
||||
}
|
||||
|
||||
variable "container_linux_channel" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_version" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_images" {
|
||||
description = "Container images to use"
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "ec2_type" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created resources."
|
||||
type = "map"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "ec2_ami" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "instance_count" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "master_iam_role" {
|
||||
type = "string"
|
||||
default = ""
|
||||
description = "IAM role to use for the instance profiles of master nodes."
|
||||
}
|
||||
|
||||
variable "master_sg_ids" {
|
||||
type = "list"
|
||||
description = "The security group IDs to be applied to the master nodes."
|
||||
}
|
||||
|
||||
variable "private_endpoints" {
|
||||
description = "If set to true, private-facing ingress resources are created."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "public_endpoints" {
|
||||
description = "If set to true, public-facing ingress resources are created."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "aws_lbs" {
|
||||
description = "List of aws_lb IDs for the Console & APIs"
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "root_volume_iops" {
|
||||
type = "string"
|
||||
default = "100"
|
||||
description = "The amount of provisioned IOPS for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_size" {
|
||||
type = "string"
|
||||
description = "The size of the volume in gigabytes for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_type" {
|
||||
type = "string"
|
||||
description = "The type of volume for the root block device."
|
||||
}
|
||||
|
||||
variable "ssh_key" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "subnet_ids" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "dns_server_ip" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "kubeconfig_content" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "user_data_ign" {
|
||||
type = "string"
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
variable "assets_s3_location" {
|
||||
type = "string"
|
||||
description = "Location on S3 of the Bootkube/Tectonic assets to use (bucket/key)"
|
||||
}
|
||||
|
||||
variable "autoscaling_group_extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created autoscaling group resources."
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "base_domain" {
|
||||
type = "string"
|
||||
description = "Domain on which the ELB records will be created"
|
||||
}
|
||||
|
||||
variable "container_linux_channel" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_version" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_images" {
|
||||
description = "Container images to use"
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "ec2_type" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created resources."
|
||||
type = "map"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "ign_s3_puller_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ec2_ami" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "instance_count" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "master_iam_role" {
|
||||
type = "string"
|
||||
default = ""
|
||||
description = "IAM role to use for the instance profiles of master nodes."
|
||||
}
|
||||
|
||||
variable "master_sg_ids" {
|
||||
type = "list"
|
||||
description = "The security group IDs to be applied to the master nodes."
|
||||
}
|
||||
|
||||
variable "private_endpoints" {
|
||||
description = "If set to true, private-facing ingress resources are created."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "public_endpoints" {
|
||||
description = "If set to true, public-facing ingress resources are created."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "aws_lbs" {
|
||||
description = "List of aws_lb IDs for the Console & APIs"
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "root_volume_iops" {
|
||||
type = "string"
|
||||
default = "100"
|
||||
description = "The amount of provisioned IOPS for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_size" {
|
||||
type = "string"
|
||||
description = "The size of the volume in gigabytes for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_type" {
|
||||
type = "string"
|
||||
description = "The type of volume for the root block device."
|
||||
}
|
||||
|
||||
variable "ssh_key" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "subnet_ids" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "ign_bootkube_service_id" {
|
||||
type = "string"
|
||||
description = "The ID of the bootkube systemd service unit"
|
||||
}
|
||||
|
||||
variable "ign_bootkube_path_unit_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_tectonic_service_id" {
|
||||
type = "string"
|
||||
description = "The ID of the tectonic installer systemd service unit"
|
||||
}
|
||||
|
||||
variable "ign_tectonic_path_unit_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_init_assets_service_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_rm_assets_service_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_rm_assets_path_unit_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "s3_bucket" {
|
||||
type = "string"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
# These subnet data-sources import external subnets from their user-supplied subnet IDs
|
||||
# whenever an external VPC is specified
|
||||
#
|
||||
data "aws_subnet" "external_worker" {
|
||||
count = "${var.external_vpc_id == "" ? 0 : length(var.external_worker_subnets)}"
|
||||
id = "${var.external_worker_subnets[count.index]}"
|
||||
}
|
||||
|
||||
data "aws_subnet" "external_master" {
|
||||
count = "${var.external_vpc_id == "" ? 0 : length(var.external_master_subnets)}"
|
||||
id = "${var.external_master_subnets[count.index]}"
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
resource "aws_elb" "tnc" {
|
||||
count = "${var.private_master_endpoints ? 1 : 0}"
|
||||
name = "${var.cluster_name}-tnc"
|
||||
subnets = ["${local.master_subnet_ids}"]
|
||||
internal = true
|
||||
security_groups = ["${aws_security_group.tnc.id}"]
|
||||
|
||||
idle_timeout = 3600
|
||||
connection_draining = true
|
||||
connection_draining_timeout = 300
|
||||
|
||||
listener {
|
||||
instance_port = 49500
|
||||
instance_protocol = "tcp"
|
||||
lb_port = 80
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
health_check {
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 2
|
||||
timeout = 3
|
||||
target = "TCP:49500"
|
||||
interval = 5
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-int",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_elb" "api_internal" {
|
||||
count = "${var.private_master_endpoints ? 1 : 0}"
|
||||
name = "${var.cluster_name}-int"
|
||||
subnets = ["${local.master_subnet_ids}"]
|
||||
internal = true
|
||||
security_groups = ["${aws_security_group.api.id}"]
|
||||
|
||||
idle_timeout = 3600
|
||||
connection_draining = true
|
||||
connection_draining_timeout = 300
|
||||
|
||||
listener {
|
||||
instance_port = 6443
|
||||
instance_protocol = "tcp"
|
||||
lb_port = 6443
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
health_check {
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 2
|
||||
timeout = 3
|
||||
target = "SSL:6443"
|
||||
interval = 5
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-int",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_elb" "api_external" {
|
||||
count = "${var.public_master_endpoints ? 1 : 0}"
|
||||
name = "${var.cluster_name}-ext"
|
||||
subnets = ["${local.master_subnet_ids}"]
|
||||
internal = false
|
||||
security_groups = ["${aws_security_group.api.id}"]
|
||||
|
||||
idle_timeout = 3600
|
||||
connection_draining = true
|
||||
connection_draining_timeout = 300
|
||||
|
||||
listener {
|
||||
instance_port = 6443
|
||||
instance_protocol = "tcp"
|
||||
lb_port = 6443
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
health_check {
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 2
|
||||
timeout = 3
|
||||
target = "SSL:6443"
|
||||
interval = 5
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-api-external",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_elb" "console" {
|
||||
name = "${var.cluster_name}-con"
|
||||
subnets = ["${local.master_subnet_ids}"]
|
||||
internal = "${var.public_master_endpoints ? false : true}"
|
||||
security_groups = ["${aws_security_group.console.id}"]
|
||||
|
||||
idle_timeout = 3600
|
||||
|
||||
listener {
|
||||
instance_port = 32001
|
||||
instance_protocol = "tcp"
|
||||
lb_port = 80
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
listener {
|
||||
instance_port = 32000
|
||||
instance_protocol = "tcp"
|
||||
lb_port = 443
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
health_check {
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 2
|
||||
timeout = 3
|
||||
target = "HTTP:32002/healthz"
|
||||
interval = 5
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-console",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
resource "aws_elb" "api_internal" {
|
||||
count = "${var.private_master_endpoints}"
|
||||
name = "${var.cluster_name}-int"
|
||||
subnets = ["${local.master_subnet_ids}"]
|
||||
internal = true
|
||||
security_groups = ["${aws_security_group.api.id}"]
|
||||
|
||||
idle_timeout = 3600
|
||||
connection_draining = true
|
||||
connection_draining_timeout = 300
|
||||
|
||||
listener {
|
||||
instance_port = 443
|
||||
instance_protocol = "tcp"
|
||||
lb_port = 443
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
health_check {
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 2
|
||||
timeout = 3
|
||||
target = "SSL:443"
|
||||
interval = 5
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-int",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_elb" "api_external" {
|
||||
count = "${var.public_master_endpoints}"
|
||||
name = "${var.custom_dns_name == "" ? var.cluster_name : var.custom_dns_name}-ext"
|
||||
subnets = ["${local.master_subnet_ids}"]
|
||||
internal = false
|
||||
security_groups = ["${aws_security_group.api.id}"]
|
||||
|
||||
idle_timeout = 3600
|
||||
connection_draining = true
|
||||
connection_draining_timeout = 300
|
||||
|
||||
listener {
|
||||
instance_port = 443
|
||||
instance_protocol = "tcp"
|
||||
lb_port = 443
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
health_check {
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 2
|
||||
timeout = 3
|
||||
target = "SSL:443"
|
||||
interval = 5
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-api-external",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_elb" "console" {
|
||||
name = "${var.custom_dns_name == "" ? var.cluster_name : var.custom_dns_name}-con"
|
||||
subnets = ["${local.master_subnet_ids}"]
|
||||
internal = "${var.public_master_endpoints ? false : true}"
|
||||
security_groups = ["${aws_security_group.console.id}"]
|
||||
|
||||
idle_timeout = 3600
|
||||
|
||||
listener {
|
||||
instance_port = 32001
|
||||
instance_protocol = "tcp"
|
||||
lb_port = 80
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
listener {
|
||||
instance_port = 32000
|
||||
instance_protocol = "tcp"
|
||||
lb_port = 443
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
health_check {
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 2
|
||||
timeout = 3
|
||||
target = "HTTP:32002/healthz"
|
||||
interval = 5
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-console",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
output "vpc_id" {
|
||||
value = "${data.aws_vpc.cluster_vpc.id}"
|
||||
}
|
||||
|
||||
# We have to do this join() & split() 'trick' because null_data_source and
|
||||
# the ternary operator can't output lists or maps
|
||||
output "master_subnet_ids" {
|
||||
value = "${local.master_subnet_ids}"
|
||||
}
|
||||
|
||||
output "worker_subnet_ids" {
|
||||
value = "${local.worker_subnet_ids}"
|
||||
}
|
||||
|
||||
output "etcd_sg_id" {
|
||||
value = "${element(concat(aws_security_group.etcd.*.id, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "master_sg_id" {
|
||||
value = "${aws_security_group.master.id}"
|
||||
}
|
||||
|
||||
output "worker_sg_id" {
|
||||
value = "${aws_security_group.worker.id}"
|
||||
}
|
||||
|
||||
output "api_sg_id" {
|
||||
value = "${aws_security_group.api.id}"
|
||||
}
|
||||
|
||||
output "console_sg_id" {
|
||||
value = "${aws_security_group.console.id}"
|
||||
}
|
||||
|
||||
output "aws_elb_api_external_id" {
|
||||
value = "${aws_elb.api_external.*.id}"
|
||||
}
|
||||
|
||||
output "aws_elb_internal_id" {
|
||||
value = "${aws_elb.api_internal.*.id}"
|
||||
}
|
||||
|
||||
output "aws_elb_console_id" {
|
||||
value = "${aws_elb.console.id}"
|
||||
}
|
||||
|
||||
output "aws_lbs" {
|
||||
value = ["${compact(concat(aws_elb.api_internal.*.id, list(aws_elb.console.id), aws_elb.api_external.*.id, aws_elb.tnc.*.id))}"]
|
||||
}
|
||||
|
||||
output "aws_api_external_dns_name" {
|
||||
value = "${element(concat(aws_elb.api_external.*.dns_name, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "aws_elb_api_external_zone_id" {
|
||||
value = "${element(concat(aws_elb.api_external.*.zone_id, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "aws_api_internal_dns_name" {
|
||||
value = "${element(concat(aws_elb.api_internal.*.dns_name, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "aws_elb_api_internal_zone_id" {
|
||||
value = "${element(concat(aws_elb.api_internal.*.zone_id, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "aws_console_dns_name" {
|
||||
value = "${aws_elb.console.dns_name}"
|
||||
}
|
||||
|
||||
output "aws_elb_console_zone_id" {
|
||||
value = "${aws_elb.console.zone_id}"
|
||||
}
|
||||
|
||||
output "aws_elb_tnc_dns_name" {
|
||||
value = "${element(concat(aws_elb.tnc.*.dns_name, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "aws_elb_tnc_zone_id" {
|
||||
value = "${element(concat(aws_elb.tnc.*.zone_id, list("")), 0)}"
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
output "vpc_id" {
|
||||
value = "${data.aws_vpc.cluster_vpc.id}"
|
||||
}
|
||||
|
||||
# We have to do this join() & split() 'trick' because null_data_source and
|
||||
# the ternary operator can't output lists or maps
|
||||
output "master_subnet_ids" {
|
||||
value = "${local.master_subnet_ids}"
|
||||
}
|
||||
|
||||
output "worker_subnet_ids" {
|
||||
value = "${local.worker_subnet_ids}"
|
||||
}
|
||||
|
||||
output "etcd_sg_id" {
|
||||
value = "${element(concat(aws_security_group.etcd.*.id, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "master_sg_id" {
|
||||
value = "${aws_security_group.master.id}"
|
||||
}
|
||||
|
||||
output "worker_sg_id" {
|
||||
value = "${aws_security_group.worker.id}"
|
||||
}
|
||||
|
||||
output "api_sg_id" {
|
||||
value = "${aws_security_group.api.id}"
|
||||
}
|
||||
|
||||
output "console_sg_id" {
|
||||
value = "${aws_security_group.console.id}"
|
||||
}
|
||||
|
||||
output "aws_elb_api_external_id" {
|
||||
value = "${aws_elb.api_external.*.id}"
|
||||
}
|
||||
|
||||
output "aws_elb_internal_id" {
|
||||
value = "${aws_elb.api_internal.*.id}"
|
||||
}
|
||||
|
||||
output "aws_elb_console_id" {
|
||||
value = "${aws_elb.console.id}"
|
||||
}
|
||||
|
||||
output "aws_lbs" {
|
||||
value = ["${compact(concat(aws_elb.api_internal.*.id, list(aws_elb.console.id), aws_elb.api_external.*.id))}"]
|
||||
}
|
||||
|
||||
output "aws_api_external_dns_name" {
|
||||
value = "${element(concat(aws_elb.api_external.*.dns_name, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "aws_elb_api_external_zone_id" {
|
||||
value = "${element(concat(aws_elb.api_external.*.zone_id, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "aws_api_internal_dns_name" {
|
||||
value = "${element(concat(aws_elb.api_internal.*.dns_name, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "aws_elb_api_internal_zone_id" {
|
||||
value = "${element(concat(aws_elb.api_internal.*.zone_id, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "aws_console_dns_name" {
|
||||
value = "${aws_elb.console.dns_name}"
|
||||
}
|
||||
|
||||
output "aws_elb_console_zone_id" {
|
||||
value = "${aws_elb.console.zone_id}"
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
resource "aws_security_group" "tnc" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_console_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
self = true
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "api" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_api_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
self = true
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 6443
|
||||
to_port = 6443
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "console" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_console_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
self = true
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
resource "aws_security_group" "api" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_api_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
self = true
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group" "console" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_console_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
self = true
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
resource "aws_security_group" "etcd" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_etcd_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
self = true
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "icmp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
self = true
|
||||
|
||||
security_groups = ["${aws_security_group.master.id}"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
from_port = 2379
|
||||
to_port = 2379
|
||||
self = true
|
||||
|
||||
security_groups = ["${aws_security_group.master.id}"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
from_port = 2380
|
||||
to_port = 2380
|
||||
self = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
resource "aws_security_group" "etcd" {
|
||||
count = "${var.enable_etcd_sg}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_etcd_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
self = true
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "icmp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
self = true
|
||||
|
||||
security_groups = ["${aws_security_group.master.id}"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
from_port = 2379
|
||||
to_port = 2379
|
||||
self = true
|
||||
|
||||
security_groups = ["${aws_security_group.master.id}"]
|
||||
}
|
||||
|
||||
ingress {
|
||||
protocol = "tcp"
|
||||
from_port = 2380
|
||||
to_port = 2380
|
||||
self = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
resource "aws_security_group" "master" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_master_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_tnc" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 49500
|
||||
to_port = 49500
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_egress" {
|
||||
type = "egress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_icmp" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "icmp"
|
||||
cidr_blocks = ["${data.aws_vpc.cluster_vpc.cidr_block}"]
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_ssh" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_http" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["${data.aws_vpc.cluster_vpc.cidr_block}"]
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_https" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["${data.aws_vpc.cluster_vpc.cidr_block}"]
|
||||
from_port = 6443
|
||||
to_port = 6445
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_heapster" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 4194
|
||||
to_port = 4194
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_heapster_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 4194
|
||||
to_port = 4194
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_flannel" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "udp"
|
||||
from_port = 4789
|
||||
to_port = 4789
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_flannel_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "udp"
|
||||
from_port = 4789
|
||||
to_port = 4789
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_node_exporter" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 9100
|
||||
to_port = 9100
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_node_exporter_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 9100
|
||||
to_port = 9100
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_kubelet_insecure" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10250
|
||||
to_port = 10250
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_kubelet_insecure_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10250
|
||||
to_port = 10250
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_kubelet_secure" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10255
|
||||
to_port = 10255
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_kubelet_secure_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10255
|
||||
to_port = 10255
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_etcd" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 2379
|
||||
to_port = 2380
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_bootstrap_etcd" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 12379
|
||||
to_port = 12380
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_services" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 30000
|
||||
to_port = 32767
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_services_from_console" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.console.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 30000
|
||||
to_port = 32767
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
resource "aws_security_group" "master" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_master_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_egress" {
|
||||
type = "egress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_icmp" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "icmp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_ssh" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_http" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_https" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_heapster" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 4194
|
||||
to_port = 4194
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_heapster_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 4194
|
||||
to_port = 4194
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_flannel" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "udp"
|
||||
from_port = 4789
|
||||
to_port = 4789
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_flannel_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "udp"
|
||||
from_port = 4789
|
||||
to_port = 4789
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_node_exporter" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 9100
|
||||
to_port = 9100
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_node_exporter_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 9100
|
||||
to_port = 9100
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_kubelet_insecure" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10250
|
||||
to_port = 10250
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_kubelet_insecure_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10250
|
||||
to_port = 10250
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_kubelet_secure" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10255
|
||||
to_port = 10255
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_kubelet_secure_from_worker" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10255
|
||||
to_port = 10255
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_etcd" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 2379
|
||||
to_port = 2380
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_bootstrap_etcd" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 12379
|
||||
to_port = 12380
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_services" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 30000
|
||||
to_port = 32767
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "master_ingress_services_from_console" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.master.id}"
|
||||
source_security_group_id = "${aws_security_group.console.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 30000
|
||||
to_port = 32767
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
resource "aws_security_group" "worker" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_worker_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_egress" {
|
||||
type = "egress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_icmp" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "icmp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_ssh" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_http" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_https" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_heapster" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 4194
|
||||
to_port = 4194
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_heapster_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 4194
|
||||
to_port = 4194
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_flannel" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "udp"
|
||||
from_port = 4789
|
||||
to_port = 4789
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_flannel_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "udp"
|
||||
from_port = 4789
|
||||
to_port = 4789
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_node_exporter" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 9100
|
||||
to_port = 9100
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_node_exporter_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 9100
|
||||
to_port = 9100
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_kubelet_insecure" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10250
|
||||
to_port = 10250
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_kubelet_insecure_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10250
|
||||
to_port = 10250
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_kubelet_secure" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10255
|
||||
to_port = 10255
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_kubelet_secure_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10255
|
||||
to_port = 10255
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_services" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 30000
|
||||
to_port = 32767
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_services_from_console" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.console.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 30000
|
||||
to_port = 32767
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
resource "aws_security_group" "worker" {
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_worker_sg",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "owned",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_egress" {
|
||||
type = "egress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_icmp" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "icmp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_ssh" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_http" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_https" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
from_port = 443
|
||||
to_port = 443
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_heapster" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 4194
|
||||
to_port = 4194
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_heapster_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 4194
|
||||
to_port = 4194
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_flannel" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "udp"
|
||||
from_port = 4789
|
||||
to_port = 4789
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_flannel_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "udp"
|
||||
from_port = 4789
|
||||
to_port = 4789
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_node_exporter" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 9100
|
||||
to_port = 9100
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_node_exporter_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 9100
|
||||
to_port = 9100
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_kubelet_insecure" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10250
|
||||
to_port = 10250
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_kubelet_insecure_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10250
|
||||
to_port = 10250
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_kubelet_secure" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10255
|
||||
to_port = 10255
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_kubelet_secure_from_master" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.master.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 10255
|
||||
to_port = 10255
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_services" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 30000
|
||||
to_port = 32767
|
||||
self = true
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "worker_ingress_services_from_console" {
|
||||
type = "ingress"
|
||||
security_group_id = "${aws_security_group.worker.id}"
|
||||
source_security_group_id = "${aws_security_group.console.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
from_port = 30000
|
||||
to_port = 32767
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
variable "cidr_block" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "base_domain" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "external_vpc_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "external_master_subnet_ids" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "external_worker_subnet_ids" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created resources."
|
||||
type = "map"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "new_master_subnet_configs" {
|
||||
description = "{az_name = new_subnet_cidr}: Empty map means create new subnets in all availability zones in region with generated cidrs"
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "new_worker_subnet_configs" {
|
||||
description = "{az_name = new_subnet_cidr}: Empty map means create new subnets in all availability zones in region with generated cidrs"
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "private_master_endpoints" {
|
||||
description = "If set to true, private-facing ingress resources are created."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "public_master_endpoints" {
|
||||
description = "If set to true, public-facing ingress resources are created."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "depends_on" {
|
||||
default = []
|
||||
type = "list"
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
variable "master_az_count" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "worker_az_count" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cidr_block" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "base_domain" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "external_vpc_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "external_master_subnets" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "external_worker_subnets" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created resources."
|
||||
type = "map"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "enable_etcd_sg" {
|
||||
description = "If set to true, security groups for etcd nodes are being created"
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "master_subnets" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "worker_subnets" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "master_azs" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "worker_azs" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "private_master_endpoints" {
|
||||
description = "If set to true, private-facing ingress resources are created."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "public_master_endpoints" {
|
||||
description = "If set to true, public-facing ingress resources are created."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "custom_dns_name" {
|
||||
type = "string"
|
||||
default = ""
|
||||
description = "DNS prefix used to construct the console and API server endpoints."
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
resource "aws_route_table" "private_routes" {
|
||||
count = "${local.new_worker_az_count}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name","${var.cluster_name}-private-${local.new_worker_subnet_azs[count.index]}",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_route" "to_nat_gw" {
|
||||
count = "${local.new_worker_az_count}"
|
||||
route_table_id = "${aws_route_table.private_routes.*.id[count.index]}"
|
||||
destination_cidr_block = "0.0.0.0/0"
|
||||
nat_gateway_id = "${element(aws_nat_gateway.nat_gw.*.id, count.index)}"
|
||||
depends_on = ["aws_route_table.private_routes"]
|
||||
}
|
||||
|
||||
resource "aws_subnet" "worker_subnet" {
|
||||
count = "${local.new_worker_az_count}"
|
||||
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
cidr_block = "${lookup(var.new_worker_subnet_configs,
|
||||
local.new_worker_subnet_azs[count.index],
|
||||
cidrsubnet(local.new_worker_cidr_range, 3, count.index),
|
||||
)}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-worker-${local.new_worker_subnet_azs[count.index]}",
|
||||
"kubernetes.io/cluster/${var.cluster_name}","shared",
|
||||
"kubernetes.io/role/internal-elb", "",
|
||||
"tectonicClusterID", "${var.cluster_id}",
|
||||
),
|
||||
var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "worker_routing" {
|
||||
count = "${local.new_worker_az_count}"
|
||||
route_table_id = "${aws_route_table.private_routes.*.id[count.index]}"
|
||||
subnet_id = "${aws_subnet.worker_subnet.*.id[count.index]}"
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
resource "aws_route_table" "private_routes" {
|
||||
count = "${var.external_vpc_id == "" ? var.worker_az_count : 0}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-private-${data.aws_availability_zones.azs.names[count.index]}",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_route" "to_nat_gw" {
|
||||
count = "${var.external_vpc_id == "" ? var.worker_az_count : 0}"
|
||||
route_table_id = "${aws_route_table.private_routes.*.id[count.index]}"
|
||||
destination_cidr_block = "0.0.0.0/0"
|
||||
nat_gateway_id = "${element(aws_nat_gateway.nat_gw.*.id, count.index)}"
|
||||
depends_on = ["aws_route_table.private_routes"]
|
||||
}
|
||||
|
||||
resource "aws_subnet" "worker_subnet" {
|
||||
count = "${var.external_vpc_id == "" ? var.worker_az_count : 0}"
|
||||
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
cidr_block = "${length(var.worker_subnets) > 1 ?
|
||||
"${element(var.worker_subnets, count.index)}" :
|
||||
"${cidrsubnet(data.aws_vpc.cluster_vpc.cidr_block, 4, count.index + var.worker_az_count)}"
|
||||
}"
|
||||
|
||||
availability_zone = "${var.worker_azs[count.index]}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-worker-${ "${length(var.worker_azs)}" > 0 ?
|
||||
"${var.worker_azs[count.index]}" :
|
||||
"${data.aws_availability_zones.azs.names[count.index]}" }",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"kubernetes.io/role/internal-elb", "",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "worker_routing" {
|
||||
count = "${var.external_vpc_id == "" ? var.worker_az_count : 0}"
|
||||
route_table_id = "${aws_route_table.private_routes.*.id[count.index]}"
|
||||
subnet_id = "${aws_subnet.worker_subnet.*.id[count.index]}"
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
resource "aws_internet_gateway" "igw" {
|
||||
count = "${local.external_vpc_mode ? 0 : 1}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-igw",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_route_table" "default" {
|
||||
count = "${var.external_vpc_id == "" ? 1 : 0}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-public",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}",
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_main_route_table_association" "main_vpc_routes" {
|
||||
count = "${local.external_vpc_mode ? 0 : 1}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
route_table_id = "${aws_route_table.default.id}"
|
||||
}
|
||||
|
||||
resource "aws_route" "igw_route" {
|
||||
count = "${local.external_vpc_mode ? 0 : 1}"
|
||||
destination_cidr_block = "0.0.0.0/0"
|
||||
route_table_id = "${aws_route_table.default.id}"
|
||||
gateway_id = "${aws_internet_gateway.igw.id}"
|
||||
}
|
||||
|
||||
resource "aws_subnet" "master_subnet" {
|
||||
count = "${local.new_master_az_count}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
cidr_block = "${lookup(var.new_master_subnet_configs,
|
||||
local.new_master_subnet_azs[count.index],
|
||||
cidrsubnet(local.new_master_cidr_range, 3, count.index),
|
||||
)}"
|
||||
|
||||
availability_zone = "${local.new_master_subnet_azs[count.index]}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-master-${local.new_master_subnet_azs[count.index]}",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "route_net" {
|
||||
count = "${local.new_master_az_count}"
|
||||
route_table_id = "${aws_route_table.default.id}"
|
||||
subnet_id = "${aws_subnet.master_subnet.*.id[count.index]}"
|
||||
}
|
||||
|
||||
resource "aws_eip" "nat_eip" {
|
||||
count = "${min(local.new_master_az_count,local.new_worker_az_count)}"
|
||||
vpc = true
|
||||
|
||||
# Terraform does not declare an explicit dependency towards the internet gateway.
|
||||
# this can cause the internet gateway to be deleted/detached before the EIPs.
|
||||
# https://github.com/coreos/tectonic-installer/issues/1017#issuecomment-307780549
|
||||
depends_on = ["aws_internet_gateway.igw"]
|
||||
}
|
||||
|
||||
resource "aws_nat_gateway" "nat_gw" {
|
||||
count = "${min(local.new_master_az_count,local.new_worker_az_count)}"
|
||||
allocation_id = "${aws_eip.nat_eip.*.id[count.index]}"
|
||||
subnet_id = "${aws_subnet.master_subnet.*.id[count.index]}"
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
resource "aws_internet_gateway" "igw" {
|
||||
count = "${var.external_vpc_id == "" ? 1 : 0}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-igw",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_route_table" "default" {
|
||||
count = "${var.external_vpc_id == "" ? 1 : 0}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-public",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_main_route_table_association" "main_vpc_routes" {
|
||||
count = "${var.external_vpc_id == "" ? 1 : 0}"
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
route_table_id = "${aws_route_table.default.id}"
|
||||
}
|
||||
|
||||
resource "aws_route" "igw_route" {
|
||||
count = "${var.external_vpc_id == "" ? 1 : 0}"
|
||||
destination_cidr_block = "0.0.0.0/0"
|
||||
route_table_id = "${aws_route_table.default.id}"
|
||||
gateway_id = "${aws_internet_gateway.igw.id}"
|
||||
}
|
||||
|
||||
resource "aws_subnet" "master_subnet" {
|
||||
count = "${var.external_vpc_id == "" ? var.master_az_count : 0}"
|
||||
|
||||
vpc_id = "${data.aws_vpc.cluster_vpc.id}"
|
||||
|
||||
cidr_block = "${length(var.master_subnets) > 1 ?
|
||||
"${element(var.master_subnets, count.index)}" :
|
||||
"${cidrsubnet(data.aws_vpc.cluster_vpc.cidr_block, 4, count.index)}"
|
||||
}"
|
||||
|
||||
availability_zone = "${var.master_azs[count.index]}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-master-${ "${length(var.master_azs)}" > 0 ?
|
||||
"${var.master_azs[count.index]}" :
|
||||
"${data.aws_availability_zones.azs.names[count.index]}" }",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "route_net" {
|
||||
count = "${var.external_vpc_id == "" ? var.master_az_count : 0}"
|
||||
route_table_id = "${aws_route_table.default.id}"
|
||||
subnet_id = "${aws_subnet.master_subnet.*.id[count.index]}"
|
||||
}
|
||||
|
||||
resource "aws_eip" "nat_eip" {
|
||||
count = "${var.external_vpc_id == "" ? min(var.master_az_count, var.worker_az_count) : 0}"
|
||||
vpc = true
|
||||
|
||||
# Terraform does not declare an explicit dependency towards the internet gateway.
|
||||
# this can cause the internet gateway to be deleted/detached before the EIPs.
|
||||
# https://github.com/coreos/tectonic-installer/issues/1017#issuecomment-307780549
|
||||
depends_on = ["aws_internet_gateway.igw"]
|
||||
}
|
||||
|
||||
resource "aws_nat_gateway" "nat_gw" {
|
||||
count = "${var.external_vpc_id == "" ? min(var.master_az_count, var.worker_az_count) : 0}"
|
||||
allocation_id = "${aws_eip.nat_eip.*.id[count.index]}"
|
||||
subnet_id = "${aws_subnet.master_subnet.*.id[count.index]}"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
locals {
|
||||
new_worker_cidr_range = "${cidrsubnet(data.aws_vpc.cluster_vpc.cidr_block,1,1)}"
|
||||
new_master_cidr_range = "${cidrsubnet(data.aws_vpc.cluster_vpc.cidr_block,1,0)}"
|
||||
}
|
||||
|
||||
resource "aws_vpc" "new_vpc" {
|
||||
count = "${var.external_vpc_id == "" ? 1 : 0}"
|
||||
cidr_block = "${var.cidr_block}"
|
||||
enable_dns_hostnames = true
|
||||
enable_dns_support = true
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}.${var.base_domain}",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
data "aws_availability_zones" "azs" {}
|
||||
|
||||
resource "aws_vpc" "new_vpc" {
|
||||
count = "${var.external_vpc_id == "" ? 1 : 0}"
|
||||
cidr_block = "${var.cidr_block}"
|
||||
enable_dns_hostnames = true
|
||||
enable_dns_support = true
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}.${var.base_domain}",
|
||||
"kubernetes.io/cluster/${var.cluster_name}", "shared",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
data "aws_vpc" "cluster_vpc" {
|
||||
# The join() hack is required because currently the ternary operator
|
||||
# evaluates the expressions on both branches of the condition before
|
||||
# returning a value. When providing and external VPC, the template VPC
|
||||
# resource gets a count of zero which triggers an evaluation error.
|
||||
#
|
||||
# This is tracked upstream: https://github.com/hashicorp/hil/issues/50
|
||||
#
|
||||
id = "${var.external_vpc_id == "" ? join(" ", aws_vpc.new_vpc.*.id) : var.external_vpc_id }"
|
||||
}
|
||||
|
||||
locals {
|
||||
master_subnet_ids = ["${split(",", var.external_vpc_id == "" ? join(",", aws_subnet.master_subnet.*.id) : join(",", data.aws_subnet.external_master.*.id))}"]
|
||||
worker_subnet_ids = ["${split(",", var.external_vpc_id == "" ? join(",", aws_subnet.worker_subnet.*.id) : join(",", data.aws_subnet.external_worker.*.id))}"]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
data "ignition_config" "main" {
|
||||
files = ["${compact(list(
|
||||
var.ign_installer_kubelet_env_id,
|
||||
var.ign_installer_runtime_mappings_id,
|
||||
var.ign_max_user_watches_id,
|
||||
var.ign_nfs_config_id,
|
||||
var.ign_ntp_dropin_id,
|
||||
var.ign_profile_env_id,
|
||||
var.ign_s3_puller_id,
|
||||
var.ign_systemd_default_env_id,
|
||||
))}",
|
||||
"${var.ign_ca_cert_id_list}",
|
||||
]
|
||||
|
||||
systemd = [
|
||||
"${var.ign_docker_dropin_id}",
|
||||
"${var.ign_iscsi_service_id}",
|
||||
"${var.ign_k8s_node_bootstrap_service_id}",
|
||||
"${var.ign_kubelet_service_id}",
|
||||
"${var.ign_locksmithd_service_id}",
|
||||
"${var.ign_update_ca_certificates_dropin_id}",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
resource "aws_s3_bucket_object" "ignition_worker" {
|
||||
bucket = "${var.s3_bucket}"
|
||||
key = "ignition_worker.json"
|
||||
content = "${data.ignition_config.main.rendered}"
|
||||
acl = "private"
|
||||
|
||||
server_side_encryption = "AES256"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-ignition-worker",
|
||||
"KubernetesCluster", "${var.cluster_name}",
|
||||
"tectonicClusterID", "${var.cluster_id}"
|
||||
), var.extra_tags)}"
|
||||
}
|
||||
|
||||
data "ignition_config" "s3" {
|
||||
replace {
|
||||
source = "${format("s3://%s/%s", var.s3_bucket, aws_s3_bucket_object.ignition_worker.key)}"
|
||||
verification = "sha512-${sha512(data.ignition_config.main.rendered)}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
variable "ssh_key" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_channel" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_version" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ec2_type" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ec2_ami" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "instance_count" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "subnet_ids" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "sg_ids" {
|
||||
type = "list"
|
||||
description = "The security group IDs to be applied."
|
||||
}
|
||||
|
||||
variable "load_balancers" {
|
||||
description = "List of ELBs to attach all worker instances to."
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created resources."
|
||||
type = "map"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "autoscaling_group_extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created autoscaling group resources."
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "root_volume_type" {
|
||||
type = "string"
|
||||
description = "The type of volume for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_size" {
|
||||
type = "string"
|
||||
description = "The size of the volume in gigabytes for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_iops" {
|
||||
type = "string"
|
||||
default = "100"
|
||||
description = "The amount of provisioned IOPS for the root block device."
|
||||
}
|
||||
|
||||
variable "worker_iam_role" {
|
||||
type = "string"
|
||||
default = ""
|
||||
description = "IAM role to use for the instance profiles of worker nodes."
|
||||
}
|
||||
|
||||
variable "base_domain" {
|
||||
type = "string"
|
||||
description = "Domain on which the ELB records will be created"
|
||||
}
|
||||
|
||||
variable "kubeconfig_content" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "user_data_ign" {
|
||||
type = "string"
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
variable "ssh_key" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "vpc_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_channel" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_version" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ec2_type" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ec2_ami" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "instance_count" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "subnet_ids" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "sg_ids" {
|
||||
type = "list"
|
||||
description = "The security group IDs to be applied."
|
||||
}
|
||||
|
||||
variable "load_balancers" {
|
||||
description = "List of ELBs to attach all worker instances to."
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created resources."
|
||||
type = "map"
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "autoscaling_group_extra_tags" {
|
||||
description = "Extra AWS tags to be applied to created autoscaling group resources."
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "root_volume_type" {
|
||||
type = "string"
|
||||
description = "The type of volume for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_size" {
|
||||
type = "string"
|
||||
description = "The size of the volume in gigabytes for the root block device."
|
||||
}
|
||||
|
||||
variable "root_volume_iops" {
|
||||
type = "string"
|
||||
default = "100"
|
||||
description = "The amount of provisioned IOPS for the root block device."
|
||||
}
|
||||
|
||||
variable "worker_iam_role" {
|
||||
type = "string"
|
||||
default = ""
|
||||
description = "IAM role to use for the instance profiles of worker nodes."
|
||||
}
|
||||
|
||||
variable "ign_s3_puller_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "s3_bucket" {
|
||||
type = "string"
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
locals {
|
||||
ami_owner = "595879546273"
|
||||
arn = "aws"
|
||||
}
|
||||
|
||||
data "aws_ami" "coreos_ami" {
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["CoreOS-${var.container_linux_channel}-${var.container_linux_version}-*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "architecture"
|
||||
values = ["x86_64"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "owner-id"
|
||||
values = ["${local.ami_owner}"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_launch_configuration" "worker_conf" {
|
||||
instance_type = "${var.ec2_type}"
|
||||
image_id = "${coalesce(var.ec2_ami, data.aws_ami.coreos_ami.image_id)}"
|
||||
name_prefix = "${var.cluster_name}-worker-"
|
||||
key_name = "${var.ssh_key}"
|
||||
security_groups = ["${var.sg_ids}"]
|
||||
iam_instance_profile = "${aws_iam_instance_profile.worker_profile.arn}"
|
||||
user_data = "${var.user_data_ign}"
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
|
||||
# Ignore changes in the AMI which force recreation of the resource. This
|
||||
# avoids accidental deletion of nodes whenever a new CoreOS Release comes
|
||||
# out.
|
||||
ignore_changes = ["image_id"]
|
||||
}
|
||||
|
||||
root_block_device {
|
||||
volume_type = "${var.root_volume_type}"
|
||||
volume_size = "${var.root_volume_size}"
|
||||
iops = "${var.root_volume_type == "io1" ? var.root_volume_iops : 0}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_autoscaling_group" "workers" {
|
||||
name = "${var.cluster_name}-workers"
|
||||
desired_capacity = "${var.instance_count}"
|
||||
max_size = "${var.instance_count * 3}"
|
||||
min_size = "${var.instance_count}"
|
||||
launch_configuration = "${aws_launch_configuration.worker_conf.id}"
|
||||
vpc_zone_identifier = ["${var.subnet_ids}"]
|
||||
|
||||
tags = [
|
||||
{
|
||||
key = "Name"
|
||||
value = "${var.cluster_name}-worker"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
{
|
||||
key = "kubernetes.io/cluster/${var.cluster_name}"
|
||||
value = "owned"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
{
|
||||
key = "tectonicClusterID"
|
||||
value = "${var.cluster_id}"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
"${var.autoscaling_group_extra_tags}",
|
||||
]
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_autoscaling_attachment" "workers" {
|
||||
count = "${length(var.load_balancers)}"
|
||||
|
||||
autoscaling_group_name = "${aws_autoscaling_group.workers.name}"
|
||||
elb = "${var.load_balancers[count.index]}"
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "worker_profile" {
|
||||
name = "${var.cluster_name}-worker-profile"
|
||||
|
||||
role = "${var.worker_iam_role == "" ?
|
||||
join("|", aws_iam_role.worker_role.*.name) :
|
||||
join("|", data.aws_iam_role.worker_role.*.name)
|
||||
}"
|
||||
}
|
||||
|
||||
data "aws_iam_role" "worker_role" {
|
||||
count = "${var.worker_iam_role == "" ? 0 : 1}"
|
||||
name = "${var.worker_iam_role}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "worker_role" {
|
||||
count = "${var.worker_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-role"
|
||||
path = "/"
|
||||
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ec2.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow",
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "worker_policy" {
|
||||
count = "${var.worker_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}_worker_policy"
|
||||
role = "${aws_iam_role.worker_role.id}"
|
||||
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:Describe*",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:AttachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:DetachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Action": "elasticloadbalancing:*",
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"s3:GetObject"
|
||||
],
|
||||
"Resource": "arn:${local.arn}:s3:::*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"autoscaling:DescribeAutoScalingGroups",
|
||||
"autoscaling:DescribeAutoScalingInstances"
|
||||
],
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
locals {
|
||||
ami_owner = "595879546273"
|
||||
arn = "aws"
|
||||
}
|
||||
|
||||
data "aws_ami" "coreos_ami" {
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["CoreOS-${var.container_linux_channel}-${var.container_linux_version}-*"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "architecture"
|
||||
values = ["x86_64"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "virtualization-type"
|
||||
values = ["hvm"]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "owner-id"
|
||||
values = ["${local.ami_owner}"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_launch_configuration" "worker_conf" {
|
||||
instance_type = "${var.ec2_type}"
|
||||
image_id = "${coalesce(var.ec2_ami, data.aws_ami.coreos_ami.image_id)}"
|
||||
name_prefix = "${var.cluster_name}-worker-"
|
||||
key_name = "${var.ssh_key}"
|
||||
security_groups = ["${var.sg_ids}"]
|
||||
iam_instance_profile = "${aws_iam_instance_profile.worker_profile.arn}"
|
||||
user_data = "${data.ignition_config.s3.rendered}"
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
|
||||
# Ignore changes in the AMI which force recreation of the resource. This
|
||||
# avoids accidental deletion of nodes whenever a new CoreOS Release comes
|
||||
# out.
|
||||
ignore_changes = ["image_id"]
|
||||
}
|
||||
|
||||
root_block_device {
|
||||
volume_type = "${var.root_volume_type}"
|
||||
volume_size = "${var.root_volume_size}"
|
||||
iops = "${var.root_volume_type == "io1" ? var.root_volume_iops : 0}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_autoscaling_group" "workers" {
|
||||
name = "${var.cluster_name}-workers"
|
||||
desired_capacity = "${var.instance_count}"
|
||||
max_size = "${var.instance_count * 3}"
|
||||
min_size = "${var.instance_count}"
|
||||
launch_configuration = "${aws_launch_configuration.worker_conf.id}"
|
||||
vpc_zone_identifier = ["${var.subnet_ids}"]
|
||||
|
||||
tags = [
|
||||
{
|
||||
key = "Name"
|
||||
value = "${var.cluster_name}-worker"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
{
|
||||
key = "kubernetes.io/cluster/${var.cluster_name}"
|
||||
value = "owned"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
{
|
||||
key = "tectonicClusterID"
|
||||
value = "${var.cluster_id}"
|
||||
propagate_at_launch = true
|
||||
},
|
||||
"${var.autoscaling_group_extra_tags}",
|
||||
]
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_autoscaling_attachment" "workers" {
|
||||
count = "${length(var.load_balancers)}"
|
||||
|
||||
autoscaling_group_name = "${aws_autoscaling_group.workers.name}"
|
||||
elb = "${var.load_balancers[count.index]}"
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "worker_profile" {
|
||||
name = "${var.cluster_name}-worker-profile"
|
||||
|
||||
role = "${var.worker_iam_role == "" ?
|
||||
join("|", aws_iam_role.worker_role.*.name) :
|
||||
join("|", data.aws_iam_role.worker_role.*.name)
|
||||
}"
|
||||
}
|
||||
|
||||
data "aws_iam_role" "worker_role" {
|
||||
count = "${var.worker_iam_role == "" ? 0 : 1}"
|
||||
name = "${var.worker_iam_role}"
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "worker_role" {
|
||||
count = "${var.worker_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-role"
|
||||
path = "/"
|
||||
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ec2.amazonaws.com"
|
||||
},
|
||||
"Effect": "Allow",
|
||||
"Sid": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "worker_policy" {
|
||||
count = "${var.worker_iam_role == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}_worker_policy"
|
||||
role = "${aws_iam_role.worker_role.id}"
|
||||
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:Describe*",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:AttachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:DetachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Action": "elasticloadbalancing:*",
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"s3:GetObject"
|
||||
],
|
||||
"Resource": "arn:${local.arn}:s3:::*",
|
||||
"Effect": "Allow"
|
||||
},
|
||||
{
|
||||
"Action" : [
|
||||
"autoscaling:DescribeAutoScalingGroups",
|
||||
"autoscaling:DescribeAutoScalingInstances"
|
||||
],
|
||||
"Resource": "*",
|
||||
"Effect": "Allow"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
resource "azurerm_availability_set" "etcd" {
|
||||
count = "${var.etcd_count > 0 ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
managed = true
|
||||
platform_fault_domain_count = "${var.fault_domains}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-etcd",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "azurerm_virtual_machine" "etcd_node" {
|
||||
count = "${var.etcd_count}"
|
||||
name = "${var.cluster_name}-etcd-${count.index}"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_interface_ids = ["${var.network_interface_ids[count.index]}"]
|
||||
vm_size = "${var.vm_size}"
|
||||
availability_set_id = "${azurerm_availability_set.etcd.id}"
|
||||
|
||||
delete_os_disk_on_termination = true
|
||||
|
||||
storage_image_reference {
|
||||
publisher = "CoreOS"
|
||||
offer = "CoreOS"
|
||||
sku = "${var.container_linux_channel}"
|
||||
version = "${var.container_linux_version}"
|
||||
}
|
||||
|
||||
storage_os_disk {
|
||||
name = "etcd-${count.index}-os-${var.storage_id}"
|
||||
managed_disk_type = "${var.storage_type}"
|
||||
create_option = "FromImage"
|
||||
caching = "ReadWrite"
|
||||
os_type = "linux"
|
||||
disk_size_gb = "${var.root_volume_size}"
|
||||
}
|
||||
|
||||
os_profile {
|
||||
computer_name = "${var.cluster_name}-etcd-${count.index}"
|
||||
admin_username = "core"
|
||||
admin_password = ""
|
||||
custom_data = "${base64encode("${data.ignition_config.etcd.*.rendered[count.index]}")}"
|
||||
}
|
||||
|
||||
os_profile_linux_config {
|
||||
disable_password_authentication = true
|
||||
|
||||
ssh_keys {
|
||||
path = "/home/core/.ssh/authorized_keys"
|
||||
key_data = "${file(var.public_ssh_key)}"
|
||||
}
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-etcd-${count.index}",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
"storage_os_disk",
|
||||
"storage_data_disk",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
data "ignition_config" "etcd" {
|
||||
count = "${var.etcd_count}"
|
||||
|
||||
systemd = [
|
||||
"${data.ignition_systemd_unit.locksmithd.*.id[count.index]}",
|
||||
"${var.ign_etcd_dropin_id_list[count.index]}",
|
||||
]
|
||||
|
||||
users = [
|
||||
"${data.ignition_user.core.id}",
|
||||
]
|
||||
|
||||
files = ["${compact(list(
|
||||
var.ign_profile_env_id,
|
||||
var.ign_systemd_default_env_id,
|
||||
))}",
|
||||
"${var.ign_etcd_crt_id_list}",
|
||||
"${var.ign_ntp_dropin_id}",
|
||||
]
|
||||
}
|
||||
|
||||
data "ignition_user" "core" {
|
||||
count = "${var.etcd_count > 0 ? 1 : 0}"
|
||||
|
||||
name = "core"
|
||||
|
||||
ssh_authorized_keys = [
|
||||
"${file(var.public_ssh_key)}",
|
||||
]
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "locksmithd" {
|
||||
count = "${var.etcd_count}"
|
||||
|
||||
name = "locksmithd.service"
|
||||
enabled = true
|
||||
|
||||
dropin = [
|
||||
{
|
||||
name = "40-etcd-lock.conf"
|
||||
|
||||
content = <<EOF
|
||||
[Service]
|
||||
Environment=REBOOT_STRATEGY=etcd-lock
|
||||
${var.tls_enabled ? "Environment=\"LOCKSMITHD_ETCD_CAFILE=/etc/ssl/etcd/ca.crt\"" : ""}
|
||||
${var.tls_enabled ? "Environment=\"LOCKSMITHD_ETCD_KEYFILE=/etc/ssl/etcd/client.key\"" : ""}
|
||||
${var.tls_enabled ? "Environment=\"LOCKSMITHD_ETCD_CERTFILE=/etc/ssl/etcd/client.crt\"" : ""}
|
||||
Environment="LOCKSMITHD_ENDPOINT=${var.tls_enabled ? "https" : "http"}://etcd-${count.index}:2379"
|
||||
EOF
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
output "etcd_vm_ids" {
|
||||
value = ["${azurerm_virtual_machine.etcd_node.*.id}"]
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
// Location is the Azure Location (East US, West US, etc)
|
||||
variable "location" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "resource_group_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
// VM Size name
|
||||
variable "vm_size" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
// Storage account type
|
||||
variable "storage_type" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "storage_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "root_volume_size" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
// Count of etcd nodes to be created.
|
||||
variable "etcd_count" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
// The base DNS domain of the cluster.
|
||||
// Example: `azure.dev.coreos.systems`
|
||||
variable "base_domain" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
// The name of the cluster.
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "public_ssh_key" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "network_interface_ids" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "versions" {
|
||||
description = "(internal) Versions of the components to use"
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "container_linux_channel" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_version" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "const_internal_node_names" {
|
||||
type = "list"
|
||||
default = ["etcd-0", "etcd-1", "etcd-2", "etcd-3", "etcd-4"]
|
||||
description = "(internal) The list of hostnames assigned to etcd member nodes."
|
||||
}
|
||||
|
||||
variable "tls_enabled" {
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "container_image" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "ign_etcd_dropin_id_list" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "fault_domains" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_etcd_crt_id_list" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "ign_profile_env_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_systemd_default_env_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_ntp_dropin_id" {
|
||||
type = "string"
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
data "ignition_config" "master" {
|
||||
files = ["${compact(list(
|
||||
data.ignition_file.cloud_provider_config.id,
|
||||
data.ignition_file.kubeconfig.id,
|
||||
var.ign_azure_udev_rules_id,
|
||||
var.ign_installer_kubelet_env_id,
|
||||
var.ign_installer_runtime_mappings_id,
|
||||
var.ign_max_user_watches_id,
|
||||
var.ign_nfs_config_id,
|
||||
var.ign_ntp_dropin_id,
|
||||
var.ign_profile_env_id,
|
||||
var.ign_systemd_default_env_id,
|
||||
))}",
|
||||
"${var.ign_ca_cert_id_list}",
|
||||
]
|
||||
|
||||
systemd = ["${compact(list(
|
||||
var.ign_docker_dropin_id,
|
||||
var.ign_locksmithd_service_id,
|
||||
var.ign_k8s_node_bootstrap_service_id,
|
||||
var.ign_kubelet_service_id,
|
||||
var.ign_tx_off_service_id,
|
||||
var.ign_bootkube_service_id,
|
||||
var.ign_tectonic_service_id,
|
||||
var.ign_bootkube_path_unit_id,
|
||||
var.ign_tectonic_path_unit_id,
|
||||
var.ign_update_ca_certificates_dropin_id,
|
||||
var.ign_iscsi_service_id,
|
||||
))}"]
|
||||
|
||||
users = [
|
||||
"${data.ignition_user.core.id}",
|
||||
]
|
||||
}
|
||||
|
||||
data "ignition_user" "core" {
|
||||
name = "core"
|
||||
|
||||
ssh_authorized_keys = [
|
||||
"${file(var.public_ssh_key)}",
|
||||
]
|
||||
}
|
||||
|
||||
data "ignition_file" "kubeconfig" {
|
||||
filesystem = "root"
|
||||
path = "/etc/kubernetes/kubeconfig"
|
||||
mode = 0644
|
||||
|
||||
content {
|
||||
content = "${var.kubeconfig_content}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_file" "cloud_provider_config" {
|
||||
filesystem = "root"
|
||||
path = "/etc/kubernetes/cloud/config"
|
||||
mode = 0600
|
||||
|
||||
content {
|
||||
content = "${var.cloud_provider_config}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
resource "azurerm_availability_set" "tectonic_masters" {
|
||||
name = "${var.cluster_name}-masters"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
managed = true
|
||||
platform_fault_domain_count = "${var.fault_domains}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-masters",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "azurerm_virtual_machine" "tectonic_master" {
|
||||
count = "${var.master_count}"
|
||||
name = "${var.cluster_name}-master-${count.index}"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_interface_ids = ["${var.network_interface_ids[count.index]}"]
|
||||
vm_size = "${var.vm_size}"
|
||||
availability_set_id = "${azurerm_availability_set.tectonic_masters.id}"
|
||||
|
||||
delete_os_disk_on_termination = true
|
||||
|
||||
storage_image_reference {
|
||||
publisher = "CoreOS"
|
||||
offer = "CoreOS"
|
||||
sku = "${var.container_linux_channel}"
|
||||
version = "${var.container_linux_version}"
|
||||
}
|
||||
|
||||
storage_os_disk {
|
||||
name = "master-${count.index}-os-${var.storage_id}"
|
||||
managed_disk_type = "${var.storage_type}"
|
||||
create_option = "FromImage"
|
||||
caching = "ReadWrite"
|
||||
os_type = "linux"
|
||||
disk_size_gb = "${var.root_volume_size}"
|
||||
}
|
||||
|
||||
os_profile {
|
||||
computer_name = "${var.cluster_name}-master-${count.index}"
|
||||
admin_username = "core"
|
||||
admin_password = ""
|
||||
custom_data = "${base64encode("${data.ignition_config.master.rendered}")}"
|
||||
}
|
||||
|
||||
os_profile_linux_config {
|
||||
disable_password_authentication = true
|
||||
|
||||
ssh_keys {
|
||||
path = "/home/core/.ssh/authorized_keys"
|
||||
key_data = "${file(var.public_ssh_key)}"
|
||||
}
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-master-${count.index}",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
"storage_os_disk",
|
||||
"storage_data_disk",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
output "master_vm_ids" {
|
||||
value = ["${azurerm_virtual_machine.tectonic_master.*.id}"]
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
variable "container_linux_channel" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_version" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cloud_provider_config" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
description = "The name of the cluster."
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "ign_azure_udev_rules_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_tx_off_service_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "kubeconfig_content" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
type = "string"
|
||||
description = "Location is the Azure Location (East US, West US, etc)"
|
||||
}
|
||||
|
||||
variable "master_count" {
|
||||
type = "string"
|
||||
description = "Count of master nodes to be created."
|
||||
}
|
||||
|
||||
variable "network_interface_ids" {
|
||||
type = "list"
|
||||
description = "List of NICs to use for master VMs"
|
||||
}
|
||||
|
||||
variable "public_ssh_key" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "resource_group_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "storage_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "storage_type" {
|
||||
type = "string"
|
||||
description = "Storage account type"
|
||||
}
|
||||
|
||||
variable "root_volume_size" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "vm_size" {
|
||||
type = "string"
|
||||
description = "VM Size name"
|
||||
}
|
||||
|
||||
variable "ign_bootkube_service_id" {
|
||||
type = "string"
|
||||
description = "The ID of the bootkube systemd service unit"
|
||||
}
|
||||
|
||||
variable "ign_bootkube_path_unit_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_tectonic_service_id" {
|
||||
type = "string"
|
||||
description = "The ID of the tectonic installer systemd service unit"
|
||||
}
|
||||
|
||||
variable "ign_tectonic_path_unit_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "fault_domains" {
|
||||
type = "string"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
variable "external_rsg_id" {
|
||||
default = ""
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "azure_location" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
# Storage ID
|
||||
resource "random_id" "storage_id" {
|
||||
byte_length = 2
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
type = "map"
|
||||
}
|
||||
|
||||
resource "azurerm_resource_group" "tectonic_cluster" {
|
||||
count = "${var.external_rsg_id == "" ? 1 : 0}"
|
||||
location = "${var.azure_location}"
|
||||
name = "tectonic-cluster-${var.cluster_name}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "tectonic-cluster-${var.cluster_name}",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
}
|
||||
|
||||
output "name" {
|
||||
value = "${var.external_rsg_id == "" ? element(concat(azurerm_resource_group.tectonic_cluster.*.name, list("")), 0) : element(split("/", var.external_rsg_id), 4)}"
|
||||
}
|
||||
|
||||
output "storage_id" {
|
||||
value = "${random_id.storage_id.hex}"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
output "udev-rules_id" {
|
||||
value = "${data.ignition_file.azure_udev_rules.id}"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
data "ignition_file" "azure_udev_rules" {
|
||||
filesystem = "root"
|
||||
path = "/etc/udev/rules.d/66-azure-storage.rules"
|
||||
mode = 0644
|
||||
|
||||
content {
|
||||
content = "${file("${path.module}/resources/66-azure-storage.rules")}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
resource "azurerm_public_ip" "api_ip" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "${var.cluster_name}_api_ip"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
public_ip_address_allocation = "static"
|
||||
domain_name_label = "${var.cluster_name}-api"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-api",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "azurerm_lb_rule" "api_lb" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "api-lb-rule-443-443"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
loadbalancer_id = "${join("", azurerm_lb.tectonic_lb.*.id)}"
|
||||
backend_address_pool_id = "${join("", azurerm_lb_backend_address_pool.api-lb.*.id)}"
|
||||
probe_id = "${azurerm_lb_probe.api_lb.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
frontend_port = 443
|
||||
backend_port = 443
|
||||
frontend_ip_configuration_name = "api"
|
||||
}
|
||||
|
||||
resource "azurerm_lb_probe" "api_lb" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "api-lb-probe-443-up"
|
||||
loadbalancer_id = "${azurerm_lb.tectonic_lb.id}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
protocol = "tcp"
|
||||
port = 443
|
||||
}
|
||||
|
||||
resource "azurerm_lb_backend_address_pool" "api-lb" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "api-lb-pool"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
loadbalancer_id = "${azurerm_lb.tectonic_lb.id}"
|
||||
}
|
||||
|
||||
resource "azurerm_lb_rule" "ssh_lb" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "ssh-lb"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
loadbalancer_id = "${join("", azurerm_lb.tectonic_lb.*.id)}"
|
||||
backend_address_pool_id = "${join("", azurerm_lb_backend_address_pool.api-lb.*.id)}"
|
||||
probe_id = "${azurerm_lb_probe.ssh_lb.id}"
|
||||
load_distribution = "SourceIP"
|
||||
|
||||
protocol = "tcp"
|
||||
frontend_port = 22
|
||||
backend_port = 22
|
||||
frontend_ip_configuration_name = "api"
|
||||
}
|
||||
|
||||
resource "azurerm_lb_probe" "ssh_lb" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "ssh-lb-22-up"
|
||||
loadbalancer_id = "${azurerm_lb.tectonic_lb.id}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
protocol = "tcp"
|
||||
port = 22
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
resource "azurerm_public_ip" "console_ip" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "${var.cluster_name}_console_ip"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
public_ip_address_allocation = "static"
|
||||
domain_name_label = "${var.cluster_name}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "azurerm_lb_rule" "console_lb_https" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "${var.cluster_name}-console-lb-rule-443-32000"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
loadbalancer_id = "${azurerm_lb.tectonic_lb.id}"
|
||||
backend_address_pool_id = "${join("", azurerm_lb_backend_address_pool.api-lb.*.id)}"
|
||||
probe_id = "${azurerm_lb_probe.console_lb.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
frontend_port = 443
|
||||
backend_port = 32000
|
||||
frontend_ip_configuration_name = "console"
|
||||
}
|
||||
|
||||
resource "azurerm_lb_rule" "console_lb_identity" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "${var.cluster_name}-console-lb-rule-80-32001"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
loadbalancer_id = "${azurerm_lb.tectonic_lb.id}"
|
||||
backend_address_pool_id = "${join("", azurerm_lb_backend_address_pool.api-lb.*.id)}"
|
||||
probe_id = "${azurerm_lb_probe.console_lb.id}"
|
||||
|
||||
protocol = "tcp"
|
||||
frontend_port = 80
|
||||
backend_port = 32001
|
||||
frontend_ip_configuration_name = "console"
|
||||
}
|
||||
|
||||
resource "azurerm_lb_probe" "console_lb" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "${var.cluster_name}-console-lb-probe-443-up"
|
||||
loadbalancer_id = "${azurerm_lb.tectonic_lb.id}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
protocol = "tcp"
|
||||
port = 32000
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
resource "azurerm_lb" "tectonic_lb" {
|
||||
count = "${var.private_cluster ? 0 : 1}"
|
||||
|
||||
name = "${var.cluster_name}-api-lb"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "api"
|
||||
public_ip_address_id = "${join("", azurerm_public_ip.api_ip.*.id)}"
|
||||
private_ip_address_allocation = "dynamic"
|
||||
}
|
||||
|
||||
frontend_ip_configuration {
|
||||
name = "console"
|
||||
public_ip_address_id = "${join("" , azurerm_public_ip.console_ip.*.id)}"
|
||||
private_ip_address_allocation = "dynamic"
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-api-lb",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
resource "azurerm_network_interface" "etcd_nic" {
|
||||
count = "${var.etcd_count}"
|
||||
name = "${var.cluster_name}-etcd-nic-${count.index}"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
|
||||
ip_configuration {
|
||||
name = "tectonic_etcd_configuration"
|
||||
subnet_id = "${var.external_master_subnet_id == "" ? join(" ", azurerm_subnet.master_subnet.*.id) : var.external_master_subnet_id }"
|
||||
private_ip_address_allocation = "dynamic"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
resource "azurerm_network_interface" "tectonic_master" {
|
||||
count = "${var.master_count}"
|
||||
name = "${var.cluster_name}-master-${count.index}"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
enable_ip_forwarding = true
|
||||
|
||||
ip_configuration {
|
||||
private_ip_address_allocation = "dynamic"
|
||||
name = "${var.cluster_name}-MasterIPConfiguration"
|
||||
subnet_id = "${var.external_master_subnet_id == "" ? join("",azurerm_subnet.master_subnet.*.id) : var.external_master_subnet_id}"
|
||||
load_balancer_backend_address_pools_ids = ["${compact(azurerm_lb_backend_address_pool.api-lb.*.id)}"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
resource "azurerm_network_interface" "tectonic_worker" {
|
||||
count = "${var.worker_count}"
|
||||
name = "${var.cluster_name}-worker-${count.index}"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
enable_ip_forwarding = true
|
||||
|
||||
ip_configuration {
|
||||
private_ip_address_allocation = "dynamic"
|
||||
name = "${var.cluster_name}-WorkerIPConfiguration"
|
||||
subnet_id = "${var.external_worker_subnet_id == "" ? join("", azurerm_subnet.worker_subnet.*.id) : var.external_worker_subnet_id}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
resource "azurerm_network_security_rule" "etcd_egress" {
|
||||
count = "${var.external_nsg_master_id == "" && var.etcd_count > 0 ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-out"
|
||||
description = "${var.cluster_name} etcd - Outbound"
|
||||
priority = 2000
|
||||
direction = "Outbound"
|
||||
access = "Allow"
|
||||
protocol = "*"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "*"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "*"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "etcd_ingress_ssh" {
|
||||
count = "${var.external_nsg_master_id == "" && var.etcd_count > 0 ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-in-ssh"
|
||||
description = "${var.cluster_name} etcd - SSH"
|
||||
priority = 400
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "22"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.ssh_network_internal}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "etcd_ingress_ssh_admin" {
|
||||
count = "${var.external_nsg_master_id == "" && var.etcd_count > 0 ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-in-ssh-external"
|
||||
description = "${var.cluster_name} etcd - SSH external"
|
||||
priority = 405
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "22"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.ssh_network_external}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "etcd_ingress_ssh_from_master" {
|
||||
count = "${var.external_nsg_master_id == "" && var.etcd_count > 0 ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-in-ssh-master"
|
||||
description = "${var.cluster_name} etcd - SSH from master"
|
||||
priority = 410
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "22"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "etcd_ingress_client_self" {
|
||||
count = "${var.external_nsg_master_id == "" && var.etcd_count > 0 ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-in-client-self"
|
||||
description = "${var.cluster_name} etcd - etcd client"
|
||||
priority = 415
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "2379"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "etcd_ingress_client_master" {
|
||||
count = "${var.external_nsg_master_id == "" && var.etcd_count > 0 ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-in-client-master"
|
||||
description = "${var.cluster_name} etcd - etcd client from master"
|
||||
priority = 420
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "2379"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "etcd_ingress_peer" {
|
||||
count = "${var.external_nsg_master_id == "" && var.etcd_count > 0 ? 1 : 0}"
|
||||
name = "${var.cluster_name}-etcd-in-peer"
|
||||
description = "${var.cluster_name} etcd - etcd peer"
|
||||
priority = 425
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "2380"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
resource "azurerm_network_security_group" "master" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
}
|
||||
|
||||
### LB rules
|
||||
resource "azurerm_network_security_rule" "alb_probe" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-alb-probe"
|
||||
description = "${var.cluster_name} master - Azure Load Balancer probe"
|
||||
priority = 295
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "*"
|
||||
source_address_prefix = "AzureLoadBalancer"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
# TODO: Fix NSG name and source
|
||||
resource "azurerm_network_security_rule" "api_ingress_https" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-api-in-https"
|
||||
description = "${var.cluster_name} Kubernetes API"
|
||||
priority = 300
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "443"
|
||||
|
||||
# TODO: Ternary on private implementation
|
||||
source_address_prefix = "*"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "console_ingress_https" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-console-in-https"
|
||||
description = "${var.cluster_name} Azure Load Balancer - Tectonic Console"
|
||||
priority = 305
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "443"
|
||||
|
||||
# TODO: Ternary on private implementation
|
||||
source_address_prefix = "*"
|
||||
destination_address_prefix = "AzureLoadBalancer"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "console_ingress_http" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-console-in-http"
|
||||
description = "${var.cluster_name} Azure Load Balancer - Tectonic Identity"
|
||||
priority = 310
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "80"
|
||||
|
||||
# TODO: Ternary on private implementation
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "AzureLoadBalancer"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
### Master node rules
|
||||
|
||||
resource "azurerm_network_security_rule" "master_egress" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-out"
|
||||
description = "${var.cluster_name} master - Outbound"
|
||||
priority = 2005
|
||||
direction = "Outbound"
|
||||
access = "Allow"
|
||||
protocol = "*"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "*"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "*"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "master_ingress_ssh" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-in-ssh"
|
||||
description = "${var.cluster_name} master - SSH"
|
||||
priority = 500
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "22"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.ssh_network_internal}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "master_ingress_ssh_admin" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-in-ssh-external"
|
||||
description = "${var.cluster_name} master - SSH external"
|
||||
priority = 505
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "22"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.ssh_network_external}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "master_ingress_flannel" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-in-udp-4789"
|
||||
description = "${var.cluster_name} master - flannel"
|
||||
priority = 510
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "UDP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "4789"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "master_ingress_node_exporter_from_master" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-in-tcp-9100-master"
|
||||
description = "${var.cluster_name} master - Prometheus node exporter from master"
|
||||
priority = 515
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "9100"
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "master_ingress_node_exporter_from_worker" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-in-tcp-9100-worker"
|
||||
description = "${var.cluster_name} master - Prometheus node exporter from worker"
|
||||
priority = 520
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "9100"
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
# TODO: Review NSG
|
||||
resource "azurerm_network_security_rule" "master_ingress_k8s_nodeport_from_alb" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-in-any-30000-32767-alb"
|
||||
description = "${var.cluster_name} master - Kubernetes NodePort range from Azure Load Balancer"
|
||||
priority = 525
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "*"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "30000-32767"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "AzureLoadBalancer"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
# TODO: Review NSG
|
||||
resource "azurerm_network_security_rule" "master_ingress_k8s_nodeport" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-in-any-30000-32767"
|
||||
description = "${var.cluster_name} master - Kubernetes NodePort range"
|
||||
priority = 530
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "*"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "30000-32767"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "*"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "master_ingress_kubelet_secure" {
|
||||
count = "${var.external_nsg_master_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-master-in-tcp-10255-vnet"
|
||||
description = "${var.cluster_name} master - kubelet"
|
||||
priority = 535
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "10255"
|
||||
|
||||
# TODO: CR on how open this should be
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "VirtualNetwork"
|
||||
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.master.name}"
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
resource "azurerm_network_security_group" "worker" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "worker_egress" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-out"
|
||||
description = "${var.cluster_name} worker - Outbound"
|
||||
priority = 2010
|
||||
direction = "Outbound"
|
||||
access = "Allow"
|
||||
protocol = "*"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "*"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "*"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.worker.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "worker_ingress_ssh" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-in-ssh"
|
||||
description = "${var.cluster_name} worker - SSH"
|
||||
priority = 600
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "22"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.ssh_network_internal}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.worker.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "worker_ingress_ssh_admin" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-in-ssh-external"
|
||||
description = "${var.cluster_name} worker - SSH external"
|
||||
priority = 605
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "22"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.ssh_network_external}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.worker.name}"
|
||||
}
|
||||
|
||||
# TODO: Determine if we need two rules for this
|
||||
resource "azurerm_network_security_rule" "worker_ingress_k8s_nodeport" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-in-any-30000-32767"
|
||||
description = "${var.cluster_name} worker - Kubernetes NodePort range"
|
||||
priority = 610
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "*"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "30000-32767"
|
||||
source_address_prefix = "VirtualNetwork"
|
||||
destination_address_prefix = "*"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.worker.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "worker_ingress_flannel" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-in-udp-4789"
|
||||
description = "${var.cluster_name} worker - flannel"
|
||||
priority = 615
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "UDP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "4789"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.worker.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "worker_ingress_kubelet_secure" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-in-tcp-10255-vnet"
|
||||
description = "${var.cluster_name} worker - kubelet"
|
||||
priority = 620
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "10255"
|
||||
|
||||
# TODO: CR on how open this should be
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "VirtualNetwork"
|
||||
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.worker.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "worker_ingress_node_exporter_from_worker" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-in-tcp-9100-vnet"
|
||||
description = "${var.cluster_name} worker - Prometheus node exporter from worker"
|
||||
priority = 625
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "9100"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.worker.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "worker_ingress_node_exporter_from_master" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-in-tcp-9100-master"
|
||||
description = "${var.cluster_name} worker - Prometheus node exporter from master"
|
||||
priority = 630
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "9100"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.worker.name}"
|
||||
}
|
||||
|
||||
resource "azurerm_network_security_rule" "worker_ingress_heapster_from_master" {
|
||||
count = "${var.external_nsg_worker_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}-worker-in-tcp-4194-master"
|
||||
description = "${var.cluster_name} worker - Heapster from master"
|
||||
priority = 635
|
||||
direction = "Inbound"
|
||||
access = "Allow"
|
||||
protocol = "TCP"
|
||||
source_port_range = "*"
|
||||
destination_port_range = "4194"
|
||||
|
||||
# TODO: Reference subnet
|
||||
source_address_prefix = "${var.vnet_cidr_block}"
|
||||
destination_address_prefix = "${var.vnet_cidr_block}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_security_group_name = "${azurerm_network_security_group.worker.name}"
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
locals {
|
||||
# A regular expression that parses a Azure subnet id to extract subnet name.
|
||||
const_id_to_subnet_name_regex = "/^/subscriptions/[-\\w]+/resourceGroups/[-\\w]+/providers/Microsoft.Network/virtualNetworks/[.\\w]+/subnets/([.\\w-]+)$/"
|
||||
|
||||
# A regular expression that parses Azure resource IDs into component identifiers
|
||||
const_id_to_group_name_regex = "/^/subscriptions/[-\\w]+/resourceGroups/([\\w()-\\.]+)/providers/[.\\w]+/[.\\w]+/([.\\w-]+)$/"
|
||||
}
|
||||
|
||||
output "vnet_id" {
|
||||
value = "${var.external_vnet_id == "" ? element(concat(azurerm_virtual_network.tectonic_vnet.*.name, list("")), 0) : replace(var.external_vnet_id, local.const_id_to_group_name_regex, "$2")}"
|
||||
}
|
||||
|
||||
output "master_subnet" {
|
||||
value = "${var.external_master_subnet_id == "" ? element(concat(azurerm_subnet.master_subnet.*.id, list("")), 0) : var.external_master_subnet_id}"
|
||||
}
|
||||
|
||||
output "worker_subnet" {
|
||||
value = "${var.external_worker_subnet_id == "" ? element(concat(azurerm_subnet.worker_subnet.*.id, list("")), 0) : var.external_worker_subnet_id}"
|
||||
}
|
||||
|
||||
output "worker_subnet_name" {
|
||||
value = "${var.external_worker_subnet_id == "" ? element(concat(azurerm_subnet.worker_subnet.*.name, list("")), 0) : replace(var.external_worker_subnet_id, local.const_id_to_subnet_name_regex, "$1")}"
|
||||
}
|
||||
|
||||
output "vnet_resource_group" {
|
||||
value = "${var.external_vnet_id == "" ? "" : replace(var.external_vnet_id, local.const_id_to_group_name_regex, "$1")}"
|
||||
}
|
||||
|
||||
# TODO: Allow user to provide their own network
|
||||
output "etcd_cidr" {
|
||||
value = "${element(concat(azurerm_subnet.master_subnet.*.address_prefix, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "master_cidr" {
|
||||
value = "${element(concat(azurerm_subnet.master_subnet.*.address_prefix, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "worker_cidr" {
|
||||
value = "${element(concat(azurerm_subnet.worker_subnet.*.address_prefix, list("")), 0)}"
|
||||
}
|
||||
|
||||
output "worker_nsg_name" {
|
||||
value = "${var.external_nsg_worker_id == "" ? element(concat(azurerm_network_security_group.worker.*.name, list("")), 0) : var.external_nsg_worker_id}"
|
||||
}
|
||||
|
||||
output "etcd_network_interface_ids" {
|
||||
value = ["${azurerm_network_interface.etcd_nic.*.id}"]
|
||||
}
|
||||
|
||||
output "etcd_endpoints" {
|
||||
value = "${azurerm_network_interface.etcd_nic.*.private_ip_address}"
|
||||
}
|
||||
|
||||
output "master_network_interface_ids" {
|
||||
value = ["${azurerm_network_interface.tectonic_master.*.id}"]
|
||||
}
|
||||
|
||||
output "worker_network_interface_ids" {
|
||||
value = ["${azurerm_network_interface.tectonic_worker.*.id}"]
|
||||
}
|
||||
|
||||
output "master_private_ip_addresses" {
|
||||
value = ["${azurerm_network_interface.tectonic_master.*.private_ip_address}"]
|
||||
}
|
||||
|
||||
output "worker_private_ip_addresses" {
|
||||
value = ["${azurerm_network_interface.tectonic_worker.*.private_ip_address}"]
|
||||
}
|
||||
|
||||
output "api_ip_addresses" {
|
||||
value = ["${split("|", var.private_cluster ? join("|", azurerm_network_interface.tectonic_master.*.private_ip_address) : join("|", azurerm_public_ip.api_ip.*.ip_address))}"]
|
||||
}
|
||||
|
||||
output "console_ip_addresses" {
|
||||
value = ["${split("|", var.private_cluster ? join("|", azurerm_network_interface.tectonic_worker.*.private_ip_address) : join("|", azurerm_public_ip.console_ip.*.ip_address))}"]
|
||||
}
|
||||
|
||||
output "ingress_fqdn" {
|
||||
value = "${var.base_domain == "" ? element(concat(azurerm_public_ip.console_ip.*.fqdn, list("")), 0) : "${var.cluster_name}.${var.base_domain}${var.private_cluster ? ":32000" : ""}"}"
|
||||
}
|
||||
|
||||
output "api_fqdn" {
|
||||
value = "${var.base_domain == "" ? element(concat(azurerm_public_ip.api_ip.*.fqdn, list("")), 0) : "${var.cluster_name}-api.${var.base_domain}"}"
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
// The base DNS domain of the cluster.
|
||||
// Example: `azure.dev.coreos.systems`
|
||||
variable "base_domain" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "resource_group_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "vnet_cidr_block" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "external_vnet_id" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "external_master_subnet_id" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "external_worker_subnet_id" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "external_nsg_master_id" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "external_nsg_worker_id" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "etcd_cidr" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "etcd_count" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "master_cidr" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "worker_cidr" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "ssh_network_internal" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "ssh_network_external" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "master_count" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "worker_count" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "private_cluster" {
|
||||
default = false
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
resource "azurerm_virtual_network" "tectonic_vnet" {
|
||||
count = "${var.external_vnet_id == "" ? 1 : 0 }"
|
||||
name = "${var.cluster_name}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
address_space = ["${var.vnet_cidr_block}"]
|
||||
location = "${var.location}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}_vnet",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "azurerm_subnet" "master_subnet" {
|
||||
count = "${var.external_master_subnet_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}_master_subnet"
|
||||
resource_group_name = "${var.external_vnet_id == "" ? var.resource_group_name : replace(var.external_vnet_id, "${var.const_id_to_group_name_regex}", "$1")}"
|
||||
virtual_network_name = "${var.external_vnet_id == "" ? join("",azurerm_virtual_network.tectonic_vnet.*.name) : replace(var.external_vnet_id, "${var.const_id_to_group_name_regex}", "$2")}"
|
||||
address_prefix = "${cidrsubnet(var.vnet_cidr_block, 4, 0)}"
|
||||
network_security_group_id = "${var.external_nsg_master_id == "" ? azurerm_network_security_group.master.id : var.external_nsg_master_id}"
|
||||
}
|
||||
|
||||
resource "azurerm_subnet" "worker_subnet" {
|
||||
count = "${var.external_worker_subnet_id == "" ? 1 : 0}"
|
||||
name = "${var.cluster_name}_worker_subnet"
|
||||
resource_group_name = "${var.external_vnet_id == "" ? var.resource_group_name : replace(var.external_vnet_id, "${var.const_id_to_group_name_regex}", "$1")}"
|
||||
virtual_network_name = "${var.external_vnet_id == "" ? join("",azurerm_virtual_network.tectonic_vnet.*.name) : replace(var.external_vnet_id, "${var.const_id_to_group_name_regex}", "$2") }"
|
||||
address_prefix = "${cidrsubnet(var.vnet_cidr_block, 4, 1)}"
|
||||
network_security_group_id = "${var.external_nsg_worker_id == "" ? azurerm_network_security_group.worker.id : var.external_nsg_worker_id}"
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
data "ignition_config" "worker" {
|
||||
files = ["${compact(list(
|
||||
data.ignition_file.cloud-provider-config.id,
|
||||
data.ignition_file.kubeconfig.id,
|
||||
var.ign_azure_udev_rules_id,
|
||||
var.ign_installer_kubelet_env_id,
|
||||
var.ign_installer_runtime_mappings_id,
|
||||
var.ign_max_user_watches_id,
|
||||
var.ign_nfs_config_id,
|
||||
var.ign_ntp_dropin_id,
|
||||
var.ign_profile_env_id,
|
||||
var.ign_systemd_default_env_id,
|
||||
))}",
|
||||
"${var.ign_ca_cert_id_list}",
|
||||
]
|
||||
|
||||
systemd = [
|
||||
"${var.ign_docker_dropin_id}",
|
||||
"${var.ign_iscsi_service_id}",
|
||||
"${var.ign_k8s_node_bootstrap_service_id}",
|
||||
"${var.ign_kubelet_service_id}",
|
||||
"${var.ign_locksmithd_service_id}",
|
||||
"${var.ign_tx_off_service_id}",
|
||||
"${var.ign_update_ca_certificates_dropin_id}",
|
||||
]
|
||||
|
||||
users = [
|
||||
"${data.ignition_user.core.id}",
|
||||
]
|
||||
}
|
||||
|
||||
data "ignition_file" "kubeconfig" {
|
||||
filesystem = "root"
|
||||
path = "/etc/kubernetes/kubeconfig"
|
||||
mode = 0644
|
||||
|
||||
content {
|
||||
content = "${var.kubeconfig_content}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_file" "cloud-provider-config" {
|
||||
filesystem = "root"
|
||||
path = "/etc/kubernetes/cloud/config"
|
||||
mode = 0600
|
||||
|
||||
content {
|
||||
content = "${var.cloud_provider_config}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_user" "core" {
|
||||
name = "core"
|
||||
|
||||
ssh_authorized_keys = [
|
||||
"${file(var.public_ssh_key)}",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
output "availability_set_name" {
|
||||
value = "${azurerm_availability_set.tectonic_workers.name}"
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
variable "container_linux_channel" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_linux_version" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cloud_provider" {
|
||||
type = "string"
|
||||
default = "azure"
|
||||
}
|
||||
|
||||
variable "cloud_provider_config" {
|
||||
description = "Content of cloud provider config"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
description = "The name of the cluster."
|
||||
}
|
||||
|
||||
variable "extra_tags" {
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "ign_azure_udev_rules_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "ign_tx_off_service_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "kubeconfig_content" {
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
type = "string"
|
||||
description = "Location is the Azure Location (East US, West US, etc)"
|
||||
}
|
||||
|
||||
variable "network_interface_ids" {
|
||||
type = "list"
|
||||
description = "List of NICs to use for master VMs"
|
||||
}
|
||||
|
||||
variable "public_ssh_key" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "resource_group_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "storage_id" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "storage_type" {
|
||||
type = "string"
|
||||
description = "Storage account type"
|
||||
}
|
||||
|
||||
variable "root_volume_size" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "tectonic_kube_dns_service_ip" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "vm_size" {
|
||||
type = "string"
|
||||
description = "VM Size name"
|
||||
}
|
||||
|
||||
variable "worker_count" {
|
||||
type = "string"
|
||||
description = "Count of worker nodes to be created."
|
||||
}
|
||||
|
||||
variable "fault_domains" {
|
||||
type = "string"
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
resource "azurerm_availability_set" "tectonic_workers" {
|
||||
name = "${var.cluster_name}-workers"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
managed = true
|
||||
platform_fault_domain_count = "${var.fault_domains}"
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-workers",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
}
|
||||
|
||||
resource "azurerm_virtual_machine" "tectonic_worker" {
|
||||
count = "${var.worker_count}"
|
||||
name = "${var.cluster_name}-worker-${count.index}"
|
||||
location = "${var.location}"
|
||||
resource_group_name = "${var.resource_group_name}"
|
||||
network_interface_ids = ["${var.network_interface_ids[count.index]}"]
|
||||
vm_size = "${var.vm_size}"
|
||||
availability_set_id = "${azurerm_availability_set.tectonic_workers.id}"
|
||||
|
||||
delete_os_disk_on_termination = true
|
||||
|
||||
storage_image_reference {
|
||||
publisher = "CoreOS"
|
||||
offer = "CoreOS"
|
||||
sku = "${var.container_linux_channel}"
|
||||
version = "${var.container_linux_version}"
|
||||
}
|
||||
|
||||
storage_os_disk {
|
||||
name = "worker-${count.index}-os-${var.storage_id}"
|
||||
managed_disk_type = "${var.storage_type}"
|
||||
create_option = "FromImage"
|
||||
caching = "ReadWrite"
|
||||
os_type = "linux"
|
||||
disk_size_gb = "${var.root_volume_size}"
|
||||
}
|
||||
|
||||
os_profile {
|
||||
computer_name = "${var.cluster_name}-worker-${count.index}"
|
||||
admin_username = "core"
|
||||
admin_password = ""
|
||||
custom_data = "${base64encode("${data.ignition_config.worker.rendered}")}"
|
||||
}
|
||||
|
||||
os_profile_linux_config {
|
||||
disable_password_authentication = true
|
||||
|
||||
ssh_keys {
|
||||
path = "/home/core/.ssh/authorized_keys"
|
||||
key_data = "${file(var.public_ssh_key)}"
|
||||
}
|
||||
}
|
||||
|
||||
tags = "${merge(map(
|
||||
"Name", "${var.cluster_name}-worker-${count.index}",
|
||||
"tectonicClusterID", "${var.cluster_id}"),
|
||||
var.extra_tags)}"
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
"storage_os_disk",
|
||||
"storage_data_disk",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
# kubeconfig (/auth/kubeconfig)
|
||||
data "template_file" "kubeconfig" {
|
||||
template = "${file("${path.module}/resources/kubeconfig")}"
|
||||
|
||||
vars {
|
||||
root_ca_cert = "${base64encode(var.root_ca_cert_pem)}"
|
||||
admin_cert = "${base64encode(var.admin_cert_pem)}"
|
||||
admin_key = "${base64encode(var.admin_key_pem)}"
|
||||
server = "${var.kube_apiserver_url}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_file" "kubeconfig" {
|
||||
filesystem = "root"
|
||||
path = "/opt/tectonic/auth/kubeconfig"
|
||||
mode = "0600"
|
||||
|
||||
content {
|
||||
content = "${data.template_file.kubeconfig.rendered}"
|
||||
}
|
||||
}
|
||||
|
||||
# kubeconfig-kubelet
|
||||
data "template_file" "kubeconfig-kubelet" {
|
||||
template = "${file("${path.module}/resources/kubeconfig-kubelet")}"
|
||||
|
||||
vars {
|
||||
root_ca_cert = "${base64encode(var.root_ca_cert_pem)}"
|
||||
client_cert = "${base64encode(var.kubelet_cert_pem)}"
|
||||
client_key = "${base64encode(var.kubelet_key_pem)}"
|
||||
server = "${var.kube_apiserver_url}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_file" "kubeconfig-kubelet" {
|
||||
filesystem = "root"
|
||||
path = "/opt/tectonic/auth/kubeconfig-kubelet"
|
||||
mode = "0600"
|
||||
|
||||
content {
|
||||
content = "${data.template_file.kubeconfig-kubelet.rendered}"
|
||||
}
|
||||
}
|
||||
|
||||
# bootkube.sh
|
||||
data "template_file" "bootkube_sh" {
|
||||
template = "${file("${path.module}/resources/bootkube.sh")}"
|
||||
|
||||
vars {
|
||||
bootkube_image = "${var.container_images["bootkube"]}"
|
||||
kube_core_renderer_image = "${var.container_images["kube_core_renderer"]}"
|
||||
tnc_operator_image = "${var.container_images["tnc_operator"]}"
|
||||
etcd_cert_signer_image = "${var.container_images["etcd_cert_signer"]}"
|
||||
etcdctl_image = "${var.container_images["etcd"]}"
|
||||
etcd_cluster = "${join(",", data.template_file.initial_cluster.*.rendered)}"
|
||||
}
|
||||
}
|
||||
|
||||
data "ignition_file" "bootkube_sh" {
|
||||
filesystem = "root"
|
||||
path = "/opt/tectonic/bootkube.sh"
|
||||
mode = "0755"
|
||||
|
||||
content {
|
||||
content = "${data.template_file.bootkube_sh.rendered}"
|
||||
}
|
||||
}
|
||||
|
||||
# bootkube.service (available as output variable)
|
||||
data "template_file" "bootkube_service" {
|
||||
template = "${file("${path.module}/resources/bootkube.service")}"
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "bootkube_service" {
|
||||
name = "bootkube.service"
|
||||
enabled = false
|
||||
content = "${data.template_file.bootkube_service.rendered}"
|
||||
}
|
||||
|
||||
data "template_file" "initial_cluster" {
|
||||
count = "${length(var.etcd_endpoints)}"
|
||||
template = "https://${var.etcd_endpoints[count.index]}:2379"
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
# Self-hosted manifests (resources/generated/manifests/)
|
||||
resource "template_dir" "bootkube" {
|
||||
source_dir = "${path.module}/resources/manifests"
|
||||
destination_dir = "./generated/manifests"
|
||||
|
||||
vars {
|
||||
hyperkube_image = "${var.container_images["hyperkube"]}"
|
||||
pod_checkpointer_image = "${var.container_images["pod_checkpointer"]}"
|
||||
kubedns_image = "${var.container_images["kubedns"]}"
|
||||
kubednsmasq_image = "${var.container_images["kubednsmasq"]}"
|
||||
kubedns_sidecar_image = "${var.container_images["kubedns_sidecar"]}"
|
||||
|
||||
# Choose the etcd endpoints to use.
|
||||
# 1. If self-hosted etcd is enabled, then use
|
||||
# var.etcd_service_ip.
|
||||
# 2. Else if no etcd TLS certificates are provided, i.e. we bootstrap etcd
|
||||
# nodes ourselves (using http), then use insecure http var.etcd_endpoints.
|
||||
# 3. Else (if etcd TLS certific are provided), then use the secure https
|
||||
# var.etcd_endpoints.
|
||||
etcd_servers = "${
|
||||
var.self_hosted_etcd != ""
|
||||
? format("https://%s:2379", cidrhost(var.service_cidr, 15))
|
||||
: var.etcd_tls_enabled
|
||||
? join(",", formatlist("https://%s:2379", var.etcd_endpoints))
|
||||
: join(",", formatlist("http://%s:2379", var.etcd_endpoints))
|
||||
}"
|
||||
|
||||
etcd_service_ip = "${cidrhost(var.service_cidr, 15)}"
|
||||
bootstrap_etcd_service_ip = "${cidrhost(var.service_cidr, 20)}"
|
||||
|
||||
cloud_provider = "${var.cloud_provider}"
|
||||
cloud_provider_config = "${var.cloud_provider_config}"
|
||||
cloud_provider_config_flag = "${var.cloud_provider_config != "" ? "- --cloud-config=/etc/kubernetes/cloud/config" : "# no cloud provider config given"}"
|
||||
|
||||
cluster_cidr = "${var.cluster_cidr}"
|
||||
service_cidr = "${var.service_cidr}"
|
||||
kube_dns_service_ip = "${cidrhost(var.service_cidr, 10)}"
|
||||
advertise_address = "${var.advertise_address}"
|
||||
|
||||
anonymous_auth = "${var.anonymous_auth}"
|
||||
oidc_issuer_url = "${var.oidc_issuer_url}"
|
||||
oidc_client_id = "${var.oidc_client_id}"
|
||||
oidc_username_claim = "${var.oidc_username_claim}"
|
||||
oidc_groups_claim = "${var.oidc_groups_claim}"
|
||||
oidc_ca_cert = "${base64encode(var.oidc_ca_cert)}"
|
||||
|
||||
kube_ca_cert = "${base64encode(var.kube_ca_cert_pem)}"
|
||||
apiserver_key = "${base64encode(var.apiserver_key_pem)}"
|
||||
apiserver_cert = "${base64encode(var.apiserver_cert_pem)}"
|
||||
serviceaccount_pub = "${base64encode(tls_private_key.service_account.public_key_pem)}"
|
||||
serviceaccount_key = "${base64encode(tls_private_key.service_account.private_key_pem)}"
|
||||
|
||||
etcd_ca_flag = "${var.etcd_ca_cert_pem != "" ? "- --etcd-cafile=/etc/kubernetes/secrets/etcd-client-ca.crt" : "# no etcd-client-ca.crt given" }"
|
||||
etcd_cert_flag = "${var.etcd_client_cert_pem != "" ? "- --etcd-certfile=/etc/kubernetes/secrets/etcd-client.crt" : "# no etcd-client.crt given" }"
|
||||
etcd_key_flag = "${var.etcd_client_key_pem != "" ? "- --etcd-keyfile=/etc/kubernetes/secrets/etcd-client.key" : "# no etcd-client.key given" }"
|
||||
|
||||
etcd_ca_cert = "${base64encode(var.etcd_ca_cert_pem)}"
|
||||
etcd_client_cert = "${base64encode(var.etcd_client_cert_pem)}"
|
||||
etcd_client_key = "${base64encode(var.etcd_client_key_pem)}"
|
||||
|
||||
kubernetes_version = "${replace(var.versions["kubernetes"], "+", "-")}"
|
||||
|
||||
master_count = "${var.master_count}"
|
||||
node_monitor_grace_period = "${var.node_monitor_grace_period}"
|
||||
pod_eviction_timeout = "${var.pod_eviction_timeout}"
|
||||
|
||||
cloud_provider_profile = "${var.cloud_provider != "" ? "${var.cloud_provider}" : "metal"}"
|
||||
cloud_config_path = "${var.cloud_config_path}"
|
||||
}
|
||||
}
|
||||
|
||||
# Self-hosted bootstrapping manifests (resources/generated/manifests-bootstrap/)
|
||||
resource "template_dir" "bootkube_bootstrap" {
|
||||
source_dir = "${path.module}/resources/bootstrap-manifests"
|
||||
destination_dir = "./generated/bootstrap-manifests"
|
||||
|
||||
vars {
|
||||
hyperkube_image = "${var.container_images["hyperkube"]}"
|
||||
etcd_image = "${var.container_images["etcd"]}"
|
||||
|
||||
# Choose the etcd endpoints to use.
|
||||
# 1. If self-hosted etcd mode is enabled, then use
|
||||
# var.etcd_service_ip.
|
||||
# 2. Else if no etcd TLS certificates are provided, i.e. we bootstrap etcd
|
||||
# nodes ourselves (using http), then use insecure http var.etcd_endpoints.
|
||||
# 3. Else (if etcd TLS certific are provided), then use the secure https
|
||||
# var.etcd_endpoints.
|
||||
etcd_servers = "${
|
||||
var.self_hosted_etcd != ""
|
||||
? format("https://%s:2379,https://127.0.0.1:12379", cidrhost(var.service_cidr, 15))
|
||||
: var.etcd_tls_enabled
|
||||
? join(",", formatlist("https://%s:2379", var.etcd_endpoints))
|
||||
: join(",", formatlist("http://%s:2379", var.etcd_endpoints))
|
||||
}"
|
||||
|
||||
etcd_ca_flag = "${var.etcd_ca_cert_pem != "" ? "- --etcd-cafile=/etc/kubernetes/secrets/etcd-client-ca.crt" : "# no etcd-client-ca.crt given" }"
|
||||
etcd_cert_flag = "${var.etcd_client_cert_pem != "" ? "- --etcd-certfile=/etc/kubernetes/secrets/etcd-client.crt" : "# no etcd-client.crt given" }"
|
||||
etcd_key_flag = "${var.etcd_client_key_pem != "" ? "- --etcd-keyfile=/etc/kubernetes/secrets/etcd-client.key" : "# no etcd-client.key given" }"
|
||||
|
||||
cloud_provider = "${var.cloud_provider}"
|
||||
cloud_provider_config = "${var.cloud_provider_config}"
|
||||
cloud_provider_config_flag = "${var.cloud_provider_config != "" ? "- --cloud-config=/etc/kubernetes/cloud/config" : "# no cloud provider config given"}"
|
||||
|
||||
advertise_address = "${var.advertise_address}"
|
||||
cluster_cidr = "${var.cluster_cidr}"
|
||||
service_cidr = "${var.service_cidr}"
|
||||
}
|
||||
}
|
||||
|
||||
# kubeconfig (resources/generated/auth/kubeconfig)
|
||||
data "template_file" "kubeconfig" {
|
||||
template = "${file("${path.module}/resources/kubeconfig")}"
|
||||
|
||||
vars {
|
||||
kube_ca_cert = "${base64encode(var.kube_ca_cert_pem)}"
|
||||
kubelet_cert = "${base64encode(var.kubelet_cert_pem)}"
|
||||
kubelet_key = "${base64encode(var.kubelet_key_pem)}"
|
||||
server = "${var.kube_apiserver_url}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "local_file" "kubeconfig" {
|
||||
content = "${data.template_file.kubeconfig.rendered}"
|
||||
filename = "./generated/auth/kubeconfig"
|
||||
}
|
||||
|
||||
# bootkube.sh (resources/generated/bootkube.sh)
|
||||
data "template_file" "bootkube_sh" {
|
||||
template = "${file("${path.module}/resources/bootkube.sh")}"
|
||||
|
||||
vars {
|
||||
bootkube_image = "${var.container_images["bootkube"]}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "local_file" "bootkube_sh" {
|
||||
content = "${data.template_file.bootkube_sh.rendered}"
|
||||
filename = "./generated/bootkube.sh"
|
||||
}
|
||||
|
||||
# bootkube.service (available as output variable)
|
||||
data "template_file" "bootkube_service" {
|
||||
template = "${file("${path.module}/resources/bootkube.service")}"
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "bootkube_service" {
|
||||
name = "bootkube.service"
|
||||
enabled = false
|
||||
content = "${data.template_file.bootkube_service.rendered}"
|
||||
}
|
||||
|
||||
# bootkube.path (available as output variable)
|
||||
data "template_file" "bootkube_path_unit" {
|
||||
template = "${file("${path.module}/resources/bootkube.path")}"
|
||||
}
|
||||
|
||||
data "ignition_systemd_unit" "bootkube_path_unit" {
|
||||
name = "bootkube.path"
|
||||
enabled = true
|
||||
content = "${data.template_file.bootkube_path_unit.rendered}"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
output "kubeconfig-kubelet" {
|
||||
value = "${data.template_file.kubeconfig-kubelet.rendered}"
|
||||
}
|
||||
|
||||
output "systemd_service_id" {
|
||||
value = "${data.ignition_systemd_unit.bootkube_service.id}"
|
||||
}
|
||||
|
||||
output "kube_dns_service_ip" {
|
||||
value = "${cidrhost(var.service_cidr, 10)}"
|
||||
}
|
||||
|
||||
output "kubeconfig_rendered" {
|
||||
value = "${data.template_file.kubeconfig.rendered}"
|
||||
}
|
||||
|
||||
output "kubeconfig-kubelet_rendered" {
|
||||
value = "${data.template_file.kubeconfig-kubelet.rendered}"
|
||||
}
|
||||
|
||||
output "ignition_file_id_list" {
|
||||
value = ["${flatten(list(
|
||||
list(
|
||||
data.ignition_file.bootkube_sh.id,
|
||||
data.ignition_file.kubeconfig.id,
|
||||
data.ignition_file.kubeconfig-kubelet.id,
|
||||
data.ignition_file.service_account_key.id,
|
||||
data.ignition_file.service_account_crt.id,
|
||||
),
|
||||
data.ignition_file.manifest_file_list.*.id,
|
||||
))}"]
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
# This output is meant to be used to inject a dependency on the generated
|
||||
# assets. As of Terraform v0.9, it is difficult to make a module depend on
|
||||
# another module (no depends_on, no triggers), or to make a data source
|
||||
# depend on a module (no depends_on, no triggers, generally no dummy variable).
|
||||
#
|
||||
# For instance, using the 'archive_file' data source against the generated
|
||||
# assets, which is a common use-case, is tricky. There is no mechanism for
|
||||
# defining explicit dependencies and the only available variables are for the
|
||||
# source, destination and archive type, leaving little opportunities for us to
|
||||
# inject a dependency. Thanks to the property described below, this output can
|
||||
# be used as part of the output filename, in order to enforce the creation of
|
||||
# the archive after the assets have been properly generated.
|
||||
#
|
||||
# Both localfile and template_dir providers compute their IDs by hashing
|
||||
# the content of the resources on disk. Because this output is computed from the
|
||||
# combination of all the resources' IDs, it can't be guessed and can only be
|
||||
# interpolated once the assets have all been created.
|
||||
output "id" {
|
||||
value = "${sha1("
|
||||
${local_file.kubeconfig.id}
|
||||
${local_file.bootkube_sh.id}
|
||||
${template_dir.bootkube.id} ${template_dir.bootkube_bootstrap.id}
|
||||
${join(" ",
|
||||
template_dir.etcd_manifests.*.id,
|
||||
template_dir.etcd_bootstrap_manifests.*.id,
|
||||
local_file.etcd_bootstrap_service.*.id,
|
||||
local_file.migrate_etcd_cluster.*.id,
|
||||
local_file.migrate_etcd_cluster_pv_backup.*.id,
|
||||
)}
|
||||
")}"
|
||||
}
|
||||
|
||||
output "kubeconfig" {
|
||||
value = "${data.template_file.kubeconfig.rendered}"
|
||||
}
|
||||
|
||||
output "systemd_service_rendered" {
|
||||
value = "${data.template_file.bootkube_service.rendered}"
|
||||
}
|
||||
|
||||
output "systemd_service_id" {
|
||||
value = "${data.ignition_systemd_unit.bootkube_service.id}"
|
||||
}
|
||||
|
||||
output "systemd_path_unit_rendered" {
|
||||
value = "${data.template_file.bootkube_path_unit.rendered}"
|
||||
}
|
||||
|
||||
output "systemd_path_unit_id" {
|
||||
value = "${data.ignition_systemd_unit.bootkube_path_unit.id}"
|
||||
}
|
||||
|
||||
output "kube_dns_service_ip" {
|
||||
value = "${cidrhost(var.service_cidr, 10)}"
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
resource "template_dir" "etcd_manifests" {
|
||||
count = "${var.self_hosted_etcd != "" ? 1 : 0}"
|
||||
source_dir = "${path.module}/resources/self-hosted-etcd/manifests"
|
||||
destination_dir = "./generated/etcd/manifests"
|
||||
|
||||
vars {
|
||||
etcd_operator_image = "${var.container_images["etcd_operator"]}"
|
||||
etcd_service_ip = "${cidrhost(var.service_cidr, 15)}"
|
||||
kenc_image = "${var.container_images["kenc"]}"
|
||||
|
||||
etcd_ca_cert = "${base64encode(var.etcd_ca_cert_pem)}"
|
||||
|
||||
etcd_server_cert = "${base64encode(var.etcd_server_cert_pem)}"
|
||||
etcd_server_key = "${base64encode(var.etcd_server_key_pem)}"
|
||||
|
||||
etcd_client_cert = "${base64encode(var.etcd_client_cert_pem)}"
|
||||
etcd_client_key = "${base64encode(var.etcd_client_key_pem)}"
|
||||
|
||||
etcd_peer_cert = "${base64encode(var.etcd_peer_cert_pem)}"
|
||||
etcd_peer_key = "${base64encode(var.etcd_peer_key_pem)}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "template_dir" "etcd_bootstrap_manifests" {
|
||||
count = "${var.self_hosted_etcd != "" ? 1 : 0}"
|
||||
source_dir = "${path.module}/resources/self-hosted-etcd/bootstrap-manifests"
|
||||
destination_dir = "./generated/etcd/bootstrap-manifests"
|
||||
|
||||
vars {
|
||||
etcd_image = "${var.container_images["etcd"]}"
|
||||
etcd_version = "${var.versions["etcd"]}"
|
||||
bootstrap_etcd_service_ip = "${cidrhost(var.service_cidr, 20)}"
|
||||
}
|
||||
}
|
||||
|
||||
data "template_file" "etcd_bootstrap_service" {
|
||||
template = "${file("${path.module}/resources/self-hosted-etcd/bootstrap-etcd-service.json")}"
|
||||
|
||||
vars {
|
||||
bootstrap_etcd_service_ip = "${cidrhost(var.service_cidr, 20)}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "local_file" "etcd_bootstrap_service" {
|
||||
count = "${var.self_hosted_etcd != "" ? 1 : 0}"
|
||||
content = "${data.template_file.etcd_bootstrap_service.rendered}"
|
||||
filename = "./generated/etcd/bootstrap-etcd-service.json"
|
||||
}
|
||||
|
||||
data "template_file" "migrate_etcd_cluster" {
|
||||
template = "${file("${path.module}/resources/self-hosted-etcd/migrate-etcd-cluster.json")}"
|
||||
|
||||
vars {
|
||||
etcd_version = "${var.versions["etcd"]}"
|
||||
bootstrap_etcd_service_ip = "${cidrhost(var.service_cidr, 20)}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "local_file" "migrate_etcd_cluster" {
|
||||
count = "${var.self_hosted_etcd == "enabled" ? 1 : 0}"
|
||||
content = "${data.template_file.migrate_etcd_cluster.rendered}"
|
||||
filename = "./generated/etcd/migrate-etcd-cluster.json"
|
||||
}
|
||||
|
||||
data "template_file" "migrate_etcd_cluster_pv_backup" {
|
||||
template = "${file("${path.module}/resources/self-hosted-etcd/migrate-etcd-cluster-pv-backup.json")}"
|
||||
|
||||
vars {
|
||||
etcd_version = "${var.versions["etcd"]}"
|
||||
bootstrap_etcd_service_ip = "${cidrhost(var.service_cidr, 20)}"
|
||||
etcd_backup_size = "${var.etcd_backup_size}"
|
||||
etcd_backup_storage_class = "${var.etcd_backup_storage_class}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "local_file" "migrate_etcd_cluster_pv_backup" {
|
||||
count = "${var.self_hosted_etcd == "pv_backup" ? 1 : 0}"
|
||||
content = "${data.template_file.migrate_etcd_cluster_pv_backup.rendered}"
|
||||
filename = "./generated/etcd/migrate-etcd-cluster.json"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
# Kubernete's Service Account (resources/generated/tls/{service-account.key,service-account.pub})
|
||||
resource "tls_private_key" "service_account" {
|
||||
algorithm = "RSA"
|
||||
rsa_bits = "2048"
|
||||
}
|
||||
|
||||
resource "local_file" "service_account_key" {
|
||||
content = "${tls_private_key.service_account.private_key_pem}"
|
||||
filename = "./generated/tls/service-account.key"
|
||||
}
|
||||
|
||||
data "ignition_file" "service_account_key" {
|
||||
filesystem = "root"
|
||||
path = "/opt/tectonic/tls/service-account.key"
|
||||
mode = "0644"
|
||||
|
||||
content {
|
||||
content = "${tls_private_key.service_account.private_key_pem}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "local_file" "service_account_crt" {
|
||||
content = "${tls_private_key.service_account.public_key_pem}"
|
||||
filename = "./generated/tls/service-account.pub"
|
||||
}
|
||||
|
||||
data "ignition_file" "service_account_crt" {
|
||||
filesystem = "root"
|
||||
path = "/opt/tectonic/tls/service-account.pub"
|
||||
mode = "0644"
|
||||
|
||||
content {
|
||||
content = "${tls_private_key.service_account.public_key_pem}"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
# Kubernete's Service Account (resources/generated/tls/{service-account.key,service-account.pub})
|
||||
resource "tls_private_key" "service_account" {
|
||||
algorithm = "RSA"
|
||||
rsa_bits = "2048"
|
||||
}
|
||||
|
||||
resource "local_file" "service_account_key" {
|
||||
content = "${tls_private_key.service_account.private_key_pem}"
|
||||
filename = "./generated/tls/service-account.key"
|
||||
}
|
||||
|
||||
resource "local_file" "service_account_crt" {
|
||||
content = "${tls_private_key.service_account.public_key_pem}"
|
||||
filename = "./generated/tls/service-account.pub"
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
variable "apiserver_cert_pem" {
|
||||
type = "string"
|
||||
description = "The API server certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "apiserver_key_pem" {
|
||||
type = "string"
|
||||
description = "The API server key in PEM format."
|
||||
}
|
||||
|
||||
variable "openshift_apiserver_cert_pem" {
|
||||
type = "string"
|
||||
description = "The Openshift API server certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "openshift_apiserver_key_pem" {
|
||||
type = "string"
|
||||
description = "The Openshift API server key in PEM format."
|
||||
}
|
||||
|
||||
variable "apiserver_proxy_cert_pem" {
|
||||
type = "string"
|
||||
description = "The API server proxy certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "apiserver_proxy_key_pem" {
|
||||
type = "string"
|
||||
description = "The API server proxy key in PEM format."
|
||||
}
|
||||
|
||||
variable "cloud_provider_config" {
|
||||
description = "Content of cloud provider config"
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_images" {
|
||||
description = "Container images to use"
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "etcd_ca_cert_pem" {
|
||||
type = "string"
|
||||
description = "The etcd CA certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "etcd_client_cert_pem" {
|
||||
type = "string"
|
||||
description = "The etcd client certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "etcd_client_key_pem" {
|
||||
type = "string"
|
||||
description = "The etcd client key in PEM format."
|
||||
}
|
||||
|
||||
variable "etcd_endpoints" {
|
||||
description = "List of etcd endpoints to connect with (hostnames/IPs only)"
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "kube_apiserver_url" {
|
||||
description = "URL used to reach kube-apiserver"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "root_ca_cert_pem" {
|
||||
type = "string"
|
||||
description = "The Root CA in PEM format."
|
||||
}
|
||||
|
||||
variable "aggregator_ca_cert_pem" {
|
||||
type = "string"
|
||||
description = "The Aggregated API Server CA in PEM format."
|
||||
}
|
||||
|
||||
variable "aggregator_ca_key_pem" {
|
||||
type = "string"
|
||||
description = "The Aggregated API Server CA key in PEM format."
|
||||
}
|
||||
|
||||
variable "kube_ca_cert_pem" {
|
||||
type = "string"
|
||||
description = "The Kubernetes CA in PEM format."
|
||||
}
|
||||
|
||||
variable "kube_ca_key_pem" {
|
||||
type = "string"
|
||||
description = "The Kubernetes CA key in PEM format."
|
||||
}
|
||||
|
||||
variable "service_serving_ca_cert_pem" {
|
||||
type = "string"
|
||||
description = "The Service Serving CA in PEM format."
|
||||
}
|
||||
|
||||
variable "service_serving_ca_key_pem" {
|
||||
type = "string"
|
||||
description = "The Service Serving CA key in PEM format."
|
||||
}
|
||||
|
||||
variable "admin_cert_pem" {
|
||||
type = "string"
|
||||
description = "The admin certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "admin_key_pem" {
|
||||
type = "string"
|
||||
description = "The admin key in PEM format."
|
||||
}
|
||||
|
||||
variable "kubelet_cert_pem" {
|
||||
type = "string"
|
||||
description = "The kubelet certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "kubelet_key_pem" {
|
||||
type = "string"
|
||||
description = "The kubelet key in PEM format."
|
||||
}
|
||||
|
||||
variable "tnc_cert_pem" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "tnc_key_pem" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "oidc_ca_cert" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "service_cidr" {
|
||||
description = "A CIDR notation IP range from which to assign service cluster IPs"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "pull_secret_path" {
|
||||
type = "string"
|
||||
description = "Path on disk to your Tectonic pull secret. Obtain this from your Tectonic Account: https://account.coreos.com."
|
||||
default = "/Users/coreos/Desktop/config.json"
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
variable "advertise_address" {
|
||||
description = "The IP address on which to advertise the apiserver to members of the cluster"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "anonymous_auth" {
|
||||
description = "Enables anonymous requests to the secure port of the API server"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "apiserver_cert_pem" {
|
||||
type = "string"
|
||||
description = "The API server certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "apiserver_key_pem" {
|
||||
type = "string"
|
||||
description = "The API server key in PEM format."
|
||||
}
|
||||
|
||||
variable "cloud_provider" {
|
||||
description = "The provider for cloud services (empty string for no provider)"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cloud_provider_config" {
|
||||
description = "Content of cloud provider config"
|
||||
type = "string"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "cluster_cidr" {
|
||||
description = "A CIDR notation IP range from which to assign pod IPs"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "container_images" {
|
||||
description = "Container images to use"
|
||||
type = "map"
|
||||
}
|
||||
|
||||
variable "etcd_tls_enabled" {
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "etcd_ca_cert_pem" {
|
||||
type = "string"
|
||||
description = "The etcd CA certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "etcd_client_cert_pem" {
|
||||
type = "string"
|
||||
description = "The etcd client certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "etcd_client_key_pem" {
|
||||
type = "string"
|
||||
description = "The etcd client key in PEM format."
|
||||
}
|
||||
|
||||
variable "etcd_endpoints" {
|
||||
description = "List of etcd endpoints to connect with (hostnames/IPs only)"
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "etcd_peer_cert_pem" {
|
||||
type = "string"
|
||||
description = "The etcd peer certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "etcd_peer_key_pem" {
|
||||
type = "string"
|
||||
description = "The etcd peer key in PEM format."
|
||||
}
|
||||
|
||||
variable "etcd_server_cert_pem" {
|
||||
type = "string"
|
||||
description = "The etcd server certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "etcd_server_key_pem" {
|
||||
type = "string"
|
||||
description = "The etcd server key in PEM format."
|
||||
}
|
||||
|
||||
variable "self_hosted_etcd" {
|
||||
type = "string"
|
||||
description = "See tectonic_self_hosted_etcd in config.tf"
|
||||
}
|
||||
|
||||
variable "kube_apiserver_url" {
|
||||
description = "URL used to reach kube-apiserver"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "kube_ca_cert_pem" {
|
||||
type = "string"
|
||||
description = "The Kubernetes CA in PEM format."
|
||||
}
|
||||
|
||||
variable "kubelet_cert_pem" {
|
||||
type = "string"
|
||||
description = "The kubelet certificate in PEM format."
|
||||
}
|
||||
|
||||
variable "kubelet_key_pem" {
|
||||
type = "string"
|
||||
description = "The kubelet key in PEM format."
|
||||
}
|
||||
|
||||
variable "master_count" {
|
||||
description = "The number of the master nodes"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "node_monitor_grace_period" {
|
||||
description = "Amount of time which we allow running Node to be unresponsive before marking it unhealthy. Must be N times more than kubelet's nodeStatusUpdateFrequency, where N means number of retries allowed for kubelet to post node status. N must be stricly > 1."
|
||||
type = "string"
|
||||
default = "40s"
|
||||
}
|
||||
|
||||
variable "oidc_ca_cert" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "oidc_client_id" {
|
||||
description = "The client ID for the OpenID Connect client"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "oidc_groups_claim" {
|
||||
description = "The OpenID claim to use for specifying user groups (string or array of strings)"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "oidc_issuer_url" {
|
||||
description = "The URL of the OpenID issuer, only HTTPS scheme will be accepted"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "oidc_username_claim" {
|
||||
description = "The OpenID claim to use as the user name"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "pod_eviction_timeout" {
|
||||
description = "The grace period for deleting pods on failed nodes. The eviction process will start after node_monitor_grace_period + pod_eviction_timeout."
|
||||
type = "string"
|
||||
default = "5m"
|
||||
}
|
||||
|
||||
variable "cloud_config_path" {
|
||||
description = "The path to the secret file that contains the cloud config contents. Either be empty ('') or ('/etc/kubernetes/cloud/config')."
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "etcd_backup_size" {
|
||||
type = "string"
|
||||
description = "The size of the PersistentVolume used to handle etcd backups"
|
||||
}
|
||||
|
||||
variable "etcd_backup_storage_class" {
|
||||
type = "string"
|
||||
description = "The name of the Kubernetes StorageClass that will be used to handle etcd backups"
|
||||
}
|
||||
|
||||
variable "service_cidr" {
|
||||
description = "A CIDR notation IP range from which to assign service cluster IPs"
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "versions" {
|
||||
description = "Container versions to use"
|
||||
type = "map"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
resource "null_resource" "bootstrapper" {
|
||||
triggers {
|
||||
endpoint = "${var.bootstrapping_host}"
|
||||
dependencies = "${join("", concat(flatten(var._dependencies)))}"
|
||||
}
|
||||
|
||||
connection {
|
||||
host = "${var.bootstrapping_host}"
|
||||
user = "core"
|
||||
agent = true
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
when = "create"
|
||||
source = "./generated"
|
||||
destination = "$HOME/tectonic"
|
||||
}
|
||||
|
||||
provisioner "remote-exec" {
|
||||
when = "create"
|
||||
|
||||
inline = [
|
||||
"sudo mkdir -p /opt",
|
||||
"sudo rm -rf /opt/tectonic",
|
||||
"sudo mv /home/core/tectonic /opt/",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
variable "bootstrapping_host" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
variable "_dependencies" {
|
||||
type = "list"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
data "external" "version" {
|
||||
count = "${var.release_version == "latest" ? 1 : 0}"
|
||||
program = ["sh", "-c", "curl https://${var.release_channel}.release.core-os.net/amd64-usr/current/version.txt | sed -n 's/COREOS_VERSION=\\(.*\\)$/{\"version\": \"\\1\"}/p'"]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
data "external" "version" {
|
||||
program = ["sh", "-c", "curl https://${var.release_channel}.release.core-os.net/amd64-usr/current/version.txt | sed -n 's/COREOS_VERSION=\\(.*\\)$/{\"version\": \"\\1\"}/p'"]
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
locals {
|
||||
// Create a map that matches the structure of the output of the external data source
|
||||
// so we can avoid running the shell script and still parse the output consistently.
|
||||
// Here, we jsonencode because ternaries can only operate on flat data types and
|
||||
// Terraform `merge` and `element` do not play nicely with maps.
|
||||
json = "${var.release_version == "latest" ? jsonencode(data.external.version.*.result) : jsonencode(map("version", var.release_version))}"
|
||||
}
|
||||
|
||||
output "version" {
|
||||
// Parse out the version from the well-known JSON of format:
|
||||
// {"version":"<version>"}
|
||||
value = "${replace(local.json, "/.*\"version\":\"(.*)\".*/", "$1")}"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
output "version" {
|
||||
value = "${var.release_version == "latest" ? data.external.version.result["version"] : var.release_version}"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
variable "release_channel" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The Container Linux update channel.
|
||||
|
||||
Examples: `stable`, `beta`, `alpha`
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "release_version" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The Container Linux version to use. Set to `latest` to select the latest available version for the selected update channel.
|
||||
|
||||
Examples: `latest`, `1465.6.0`
|
||||
EOF
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
variable "release_channel" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The Container Linux update channel.
|
||||
|
||||
Examples: `stable`, `beta`, `alpha`
|
||||
EOF
|
||||
}
|
||||
|
||||
variable "release_version" {
|
||||
type = "string"
|
||||
|
||||
description = <<EOF
|
||||
The Container Linux version to use. Set to `latest` to select the latest available version for the selected update channel.
|
||||
|
||||
Examples: `latest`, `1465.6.0`
|
||||
EOF
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user