diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..077902e --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# used for testing +*.tfvars + +# Compiled files +*.tfstate +*.tfstate.backup + +# Module directory +.terraform/ + +# terraform log +*.log + +# auto-generated key pair file +*.pem + +# tools files +.DS_Store +.idea + +# others +*.bak +*.bk + diff --git a/README.md b/README.md new file mode 100644 index 0000000..94d8b07 --- /dev/null +++ b/README.md @@ -0,0 +1,128 @@ +Alicloud ECS Instance Terraform Module In VPC +terraform-alicloud-ecs-instance +===================================================================== + +A terraform module to provide ECS instances in Alicloud VPC. + +- It assumes you have one VPC and VSwitch and you want to put the new instances to the VPC. If not, you can launch a new one by module [terraform-alicloud-vpc](https://github.com/alibaba/terraform-alicloud-vpc) +- It assumes you have several security groups in the VPC and you want to join the new instances into them. If not, you can launch one or more groups by module [terraform-alicloud-security-group](https://github.com/alibaba/terraform-alicloud-security-group) +- If you have no idea some parametes, such as instance type, availability zone and image id, + the module will provide default values according to some input parameters, such as `image_name_regex`, `cpu_core_count`, `memory_size` and so on. + + +Module Input Variables +---------------------- + +The module aim to create one or more instances and disks in the VPC. Its input variables contains VSwitch, Security Group, ECS Disks and ECS Instances. + +#### Common Input vairables + +- `alicloud_access_key` - The Alicloud Access Key ID to launch resources +- `alicloud_secret_key` - The Alicloud Access Secret Key to launch resources +- `region` - The region to launch resources +- `availability_zone` - The availability zone ID to launch ECS Instances and ECS Disks - default to a zone ID retrieved by zones' data source +- `number_format` - The number format used to mark multiple resources - default to "%02d" + +`Note`: If you specify the `vswitch_id`, the `availability_zone` would be ignore when launching ECS instances. +#### Instance Types Data Source Input Variables + +- `image_name_regex` - The ECS image's name regex used to fetch latest specified system images - default to "^ubuntu_14.*_64" and it would return a latest 64bit Ubuntu Image + +### Instance typs Variables + +- `cpu_core_count` - CPU core count used to fetch instance types - default to 1 +- `memory_size` - Memory size used to fetch instance types - default to 2 + +#### VSwitch Input Variables + +- `vswitch_id` - VSwitch ID to launch new ECS instances + +#### Security Groups Input Variables + +- `group_ids` - List of Security Group IDs to launch new ECS instances + +#### ECS Disk Input Variables + +- `number_of_disks` - The number disks you want to launch - default to 0 +- `disk_name` - ECS disk name to mark data disk(s) - default to "TF_ECS_Disk" +- `disk_category` - ECS disk category to launch data disk(s) - choices to ["cloud_ssd", "cloud_efficiency"] - default to "cloud_efficiency" +- `disk_size` - ECS disk size to launch data disk(s) - default to 40 +- `disk_tags` - A map for setting ECS disk tags - default to + + disk_tags = { + created_by = "Terraform" + created_from = "module-tf-alicloud-ecs-instance" + } + +#### ECS Instance Input Variables + +- `number_of_instances` - The number of instances you want to launch - default to 1 +- `image_id` - The image id to use - default to an Ubuntu-64bit image ID retrieved by images' data source +- `instance_type` - The ECS instance type, e.g. ecs.n4.small, - default to a 1Core 2GB instance type retrieved by instance_types' data source +- `instance_name` - ECS instance name to mark instance(s) - default to "TF_ECS_Instance" +- `host_name` - ECS instance host name to configure instance(s) - default to "TF_ECS_Host_Name" +- `system_category` - ECS disk category to launch system disk - choices to ["cloud_ssd", "cloud_efficiency"] - default to "cloud_efficiency" +- `system_size` - ECS disk size to launch system disk - default to 40 +- `allocate_public_ip` - Whether to allocate public for instance(s) - default to true +- `internet_charge_type` - The internet charge type for setting instance network - choices["PayByTraffic", "PayByBandwidth"] - default to "PayByTraffic" +- `internet_max_bandwidth_out` - The max out bandwidth for setting instance network - default to 10 +- `instance_charge_type` - The instance charge type - choices to ["PrePaid", "PostPaid"] - default to "PostPaid" +- `period` - The instance charge period when instance charge type is 'PrePaid' - default to 1 +- `key_name` - The instance key pair name for SSH keys +- `password` - The instance password +- `instance_tags` - A map for setting ECS Instance tags - default to + + instance_tags = { + created_by = "Terraform" + created_from = "module-tf-alicloud-ecs-instance" + } + + +Usage +----- +You can use this in your terraform template with the following steps. + +1. Adding a module resource to your template, e.g. main.tf + + module "tf-instances" { + source = "github.com/terraform-community-modules/terraform-alicloud-ecs-instance" + + alicloud_access_key = "${var.alicloud_access_key}" + alicloud_secret_key = "${var.alicloud_secret_key}" + region = "${var.region}" + + vswitch_id = "${var.vswitch_id}" + group_ids = "${var.group_ids}" + + disk_category = "cloud_ssd" + disk_name = "my_module_disk" + disk_size = "50" + number_of_disks = 2 + + instance_name = "my_module_instances" + host_name = "my_host" + internet_charge_type = "PayByTraffic" + number_of_instances = "2" + + key_name = "${var.key_name}" + + } + +2. Setting values for the following variables, either through terraform.tfvars or environment variables or -var arguments on the CLI + +- alicloud_access_key +- alicloud_secret_key +- region +- key_name +- vswitch_id +- group_ids + +Module Output Variables +----------------------- + +- instance_ids - List of new instance ids +- disk_ids - List of new data disk ids + +Authors +------- +Created and maintained by He Guimin(@xiaozhu36, heguimin36@163.com) \ No newline at end of file diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..4379b34 --- /dev/null +++ b/main.tf @@ -0,0 +1,88 @@ +// Provider specific configs +provider "alicloud" { + access_key = "${var.alicloud_access_key}" + secret_key = "${var.alicloud_secret_key}" + region = "${var.region}" +} + +// Images data source for image_id +data "alicloud_images" "default" { + most_recent = true + owners = "system" + name_regex = "${var.image_name_regex}" +} + +// Instance_types data source for instance_type +data "alicloud_instance_types" "default" { + cpu_core_count = "${var.cpu_core_count}" + memory_size = "${var.memory_size}" +} + +// Zones data source for availability_zone +data "alicloud_zones" "default" { + available_disk_category = "${var.disk_category}" + available_instance_type = "${data.alicloud_instance_types.default.instance_types.0.id}" +} + +// ECS Instance Resource for Module +resource "alicloud_instance" "instances" { + count = "${var.number_of_instances}" + + image_id = "${var.image_id == "" ? data.alicloud_images.default.images.0.id : var.image_id }" + availability_zone = "${var.vswitch_id != "" ? "" : var.availability_zone == "" ? data.alicloud_zones.default.zones.0.id : var.availability_zone}" + instance_type = "${var.instance_type == "" ? data.alicloud_instance_types.default.instance_types.0.id : var.instance_type}" + security_groups = ["${var.group_ids}"] + + instance_name = "${var.number_of_instances < 2 ? var.instance_name : format("%s-%s", var.instance_name, format(var.number_format, count.index+1))}" + host_name = "${var.number_of_instances < 2 ? var.host_name : format("%s-%s", var.host_name, format(var.number_format, count.index+1))}" + + internet_charge_type = "${var.internet_charge_type}" + internet_max_bandwidth_out = "${var.internet_max_bandwidth_out}" + + allocate_public_ip = "${var.allocate_public_ip}" + + instance_charge_type = "${var.instance_charge_type}" + system_disk_category = "${var.system_category}" + system_disk_size = "${var.system_size}" + + password = "${var.password}" + + vswitch_id = "${var.vswitch_id}" + + period = "${var.period}" + + tags { + created_by = "${lookup(var.instance_tags, "created_by")}" + created_from = "${lookup(var.instance_tags, "created_from")}" + } +} + +// ECS Disk Resource for Module +resource "alicloud_disk" "disks" { + count = "${var.number_of_disks}" + + availability_zone = "${var.availability_zone == "" ? data.alicloud_zones.default.zones.0.id : var.availability_zone}" + name = "${var.number_of_disks < 2 ? var.disk_name : format("%s-%s", var.disk_name, format(var.number_format, count.index+1))}" + category = "${var.disk_category}" + size = "${var.disk_size}" + + tags { + created_by = "${lookup(var.disk_tags, "created_by")}" + created_from = "${lookup(var.disk_tags, "created_from")}" + } +} + +// Attach ECS disks to instances for Module +resource "alicloud_disk_attachment" "disk_attach" { + count = "${(var.number_of_instances > 0 && var.number_of_disks > 0) ? var.number_of_disks : 0}" + disk_id = "${element(alicloud_disk.disks.*.id, count.index)}" + instance_id = "${element(alicloud_instance.instances.*.id, count.index%var.number_of_instances)}" +} + +// Attach key pair to instances for Module +resource "alicloud_key_pair_attchment" "default" { + count = "${var.number_of_instances > 0 && var.key_name != "" ? 1 : 0}" + + key_name = "${var.key_name}" + instance_ids = ["${alicloud_instance.instances.*.id}"] +} \ No newline at end of file diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..93b43d0 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,9 @@ +// Output the IDs of the ECS instances created +output "instance_ids" { + value = "${join(",", alicloud_instance.instances.*.id)}" +} + +// Output the IDs of the ECS disks created +output "disk_ids" { + value = "${join(",", alicloud_disk.disks.*.id)}" +} \ No newline at end of file diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..bdec8ea --- /dev/null +++ b/variables.tf @@ -0,0 +1,156 @@ +# common variables +variable "alicloud_access_key" { + description = "The Alicloud Access Key ID to launch resources." + default = "" +} +variable "alicloud_secret_key" { + description = "The Alicloud Access Secret Key to launch resources." + default = "" +} +variable "region" { + description = "The region to launch resources." + default = "" +} +variable "availability_zone" { + description = "The available zone to launch ecs instance and other resources." + default = "" +} +variable "number_format" { + description = "The number format used to output." + default = "%02d" +} + +# Image variables +variable "image_name_regex" { + description = "The ECS image's name regex used to fetch specified image." + default = "^ubuntu_14.*_64" +} + +# Instance typs variables +variable "cpu_core_count" { + description = "CPU core count used to fetch instance types." + default = 1 +} + +variable "memory_size" { + description = "Memory size used to fetch instance types." + default = 2 +} + +# VSwitch ID +variable "vswitch_id" { + description = "The vswitch id used to launch one or more instances." +} + +# Security Group variables +variable "group_ids" { + description = "List of security group ids used to join ECS instances." + type = "list" +} + +# Key pair variables +variable "key_name" { + description = "The key pair name used to attach one or more instances." + default = "" +} + +# Disk variables +variable "disk_name" { + description = "The data disk name used to mark one or more data disks." + default = "TF_ECS_Disk" +} + +variable "disk_category" { + description = "The data disk category used to launch one or more data disks." + default = "cloud_efficiency" +} + +variable "disk_size" { + description = "The data disk size used to launch one or more data disks." + default = "40" +} + +variable "disk_tags" { + description = "Used to mark specified ecs data disks." + type = "map" + default = { + created_by = "Terraform" + created_from = "module-tf-alicloud-ecs-instance" + } +} + +variable "number_of_disks" { + description = "The number of launching disks one time." + default = 0 +} + +# Ecs instance variables +variable "image_id" { + description = "The image id used to launch one or more ecs instances." + default = "" +} +variable "instance_type" { + description = "The instance type used to launch one or more ecs instances." + default = "" +} +variable "system_category" { + description = "The system disk category used to launch one or more ecs instances." + default = "cloud_efficiency" +} +variable "system_size" { + description = "The system disk size used to launch one or more ecs instances." + default = "40" +} +variable "instance_name" { + description = "The instance name used to mark one or more instances." + default = "TF-ECS-Instance" +} + +variable "host_name" { + description = "The instance host name used to configure one or more instances.." + default = "TF-ECS-Host-Name" +} + +variable "password" { + description = "The password of instance." + default = "" +} + +variable "allocate_public_ip" { + description = "Default to allocate public ip for new instances." + default = true +} + +variable "internet_charge_type" { + description = "The internet charge type of instance. Choices are 'PayByTraffic' and 'PayByBandwidth'." + default = "PayByTraffic" +} + +variable "internet_max_bandwidth_out" { + description = "The maximum internet out bandwidth of instance.." + default = 10 +} + +variable "instance_charge_type" { + description = "The charge type of instance. Choices are 'PostPaid' and 'PrePaid'." + default = "PostPaid" +} + +variable "period" { + description = "The period of instance when instance charge type is 'PrePaid'." + default = 1 +} + +variable "instance_tags" { + description = "Used to mark specified ecs instance." + type = "map" + default = { + created_by = "Terraform" + created_from = "module-tf-alicloud-ecs-instance" + } +} + +variable "number_of_instances" { + description = "The number of launching instances one time." + default = 1 +} \ No newline at end of file