/terraform-ibm-landing-zone-vsi

Creates virtual server instances (VSI) across multiple subnets with any number of block storage volumes that are connected by any number of load balancers

Primary LanguageHCLApache License 2.0Apache-2.0

IBM Secure Landing Zone VSI Module

Graduated (Supported) semantic-release pre-commit latest release Renovate enabled

This module creates virtual server instances (VSI) across multiple subnets with any number of block storage volumes that are connected by any number of load balancers. vsi-module

Overview

terraform-ibm-landing-zone-vsi

Prerequisites

  • A VPC
  • A VPC SSH key

Virtual servers

This module creates virtual servers across any number of subnets in a single VPC that is connected by a single security group. You can specify the number of virtual servers to provision on each subnet by using the vsi_per_subnet variable. Virtual servers use the prefix variable to dynamically create names. These names are also used as the Terraform address for each virtual server, which allows for easy reference.

module.vsi["test-vsi"].ibm_is_instance.vsi["test-vsi-1"]
module.vsi["test-vsi"].ibm_is_instance.vsi["test-vsi-2"]
module.vsi["test-vsi"].ibm_is_instance.vsi["test-vsi-3"]

Block storage volumes

This module creates any number of identical block storage volumes. One storage volume that is specified in the volumes variable is created and attached to each virtual server. These block storage volumes use the virtual server name and the volume name to create easily identifiable and manageable addresses within Terraform:

module.vsi["test-vsi"].ibm_is_volume.volume["test-vsi-1-one"]
module.vsi["test-vsi"].ibm_is_volume.volume["test-vsi-2-one"]
module.vsi["test-vsi"].ibm_is_volume.volume["test-vsi-3-one"]
module.vsi["test-vsi"].ibm_is_volume.volume["test-vsi-1-two"]
module.vsi["test-vsi"].ibm_is_volume.volume["test-vsi-2-two"]
module.vsi["test-vsi"].ibm_is_volume.volume["test-vsi-3-two"]

Reserved IP addresses

By setting the manage_reserved_ips to true, this Terraform module will manage VPC reserved IPs for all VSI instances. In the case where the VSI instances would need to be recreated by this module (such as rolling back to a snapshot volume), the new instances will retain the same reserved IP from their previous deployment.


Static boot volume names

The default boot volume names created for VSI instances are four-word random names, which are regenerated if the VSI is recreated. If you set the use_static_boot_volume_name to true, the boot volume name for each VSI will not be random and will have a name that will be used again when recreated. This static name is of the format hostname-boot. If the VSI is recreated by Terraform for any reason, the exact same boot volume name will be used for the new instance.

Example of static boot volume name: "my-prefix-0a2b-001-boot"


Floating IP addresses

By using the enable_floating_ip, a floating IP address is assigned to each VSI created by this module. This floating IP address is displayed in the output, if provisioned.


Load balancers

This module creates any number of application load balancers to balance traffic between all virtual servers that are created by this module. Each load balancer can optionally be added to its own security group. Use the load_balancers variable to configure the back-end pool and front-end listener for each load balancer.


Storage Volume Snapshot support

This module supports volume snapshots for both VSI boot volumes and attached block storage volumes. This feature can be used in either of the following scenarios:

  1. Create new VSI instances using existing volume snapshots.
  2. Roll back currently deployed VSI instances to existing volume snapshots. NOTE: if the boot volume is restored from a snapshot, all VSI instances will be recreated, and will retain most or all of their previous configuration (see note about Reserved IP addresses above)

There are three methods you can use to specify volume snapshots for your deployment:

  1. Specify individual Snapshot Ids using the boot_volume_snapshot_id and block_storage_volumes.snapshot_id input variables
  2. Specify a Snapshot Consistency Group Id using the snapshot_consistency_group_id input variable (see explanation below)
  3. A combination of specific Snapshot Ids and Consistency Group Ids, with specific Snapshot Ids taking precedence over Consistency Group Id snapshots, useful in situations where you may want to override one or more of the Consistency Group snapshots

Snapshot Consistency Group logic explained: If a snapshot_consistency_group_id is passed into this module, the snapshots belonging to that group will be queried for their "service_tags" that were applied at group creation. These tags will contain an index that identifies the snapshot within the group as belonging to either the boot volume of the instance (index 0), or one of the attached block storage volumes (index 1..n). These indexes are used to match up each group snapshot with the boot volume of the instance (which is always index 0), as well as any additional required volumes from the block_storage_volumes input variable, using the order of the input variable against the tag index (first block_storage_volume in input array = index 1, second = index 2, and so on). If there is a mismatch of group snapshots to the required storage specified in module inputs, then any of the extra snapshots or volumes will simply be ignored in the matching logic.

NOTE: Snapshot and Consistency Group creation are not a part of this module and should be handled elsewhere.


Usage

module vsi {
  source                           = "terraform-ibm-modules/landing-zone-vsi/ibm"
  version                          = "X.X.X" # Replace "X.X.X" with a release version to lock into a specific release
  resource_group_id                = var.resource_group_id
  prefix                           = var.prefix
  tags                             = var.tags
  access_tags                      = var.access_tags
  vpc_id                           = var.vpc_id
  subnets                          = var.subnets
  image_id                         = var.image_id
  ssh_key_ids                      = var.ssh_key_ids
  machine_type                     = var.machine_type
  vsi_per_subnet                   = var.vsi_per_subnet
  user_data                        = var.user_data
  boot_volume_encryption_key       = var.boot_volume_encryption_key
  enable_floating_ip               = var.enable_floating_ip
  allow_ip_spoofing                = var.allow_ip_spoofing
  create_security_group            = var.create_security_group
  security_group                   = var.security_group
  security_group_ids               = var.security_group_ids
  block_storage_volumes            = var.block_storage_volumes
  load_balancers                   = var.load_balancers
  secondary_subnets                = var.secondary_subnets
  secondary_use_vsi_security_group = var.secondary_use_vsi_security_group
  secondary_allow_ip_spoofing      = var.secondary_allow_ip_spoofing
}

Required IAM access policies

You need the following permissions to run this module.

  • Account Management
    • Resource Group service
      • Viewer platform access
  • IAM Services
    • VPC Infrastructure Services service
      • Editor platform access

Requirements

Name Version
terraform >= 1.3.0
ibm >= 1.65.0, < 2.0.0
time >= 0.9.1, < 1.0.0

Modules

No modules.

Resources

Name Type
ibm_iam_authorization_policy.block_storage_policy resource
ibm_is_floating_ip.secondary_fip resource
ibm_is_floating_ip.vsi_fip resource
ibm_is_instance.vsi resource
ibm_is_lb.lb resource
ibm_is_lb_listener.listener resource
ibm_is_lb_pool.pool resource
ibm_is_lb_pool_member.alb_pool_members resource
ibm_is_lb_pool_member.nlb_pool_members resource
ibm_is_security_group.security_group resource
ibm_is_security_group_rule.security_group_rules resource
ibm_is_subnet_reserved_ip.vsi_ip resource
ibm_is_volume.volume resource
time_sleep.wait_for_authorization_policy resource
ibm_is_snapshot.snapshots_from_group data source
ibm_is_snapshot_consistency_group.snapshot_group data source
ibm_is_vpc.vpc data source

Inputs

Name Description Type Default Required
access_tags A list of access tags to apply to the VSI resources created by the module. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial. list(string) [] no
allow_ip_spoofing Allow IP spoofing on the primary network interface bool false no
block_storage_volumes List describing the block storage volumes that will be attached to each vsi
list(
object({
name = string
profile = string
capacity = optional(number)
iops = optional(number)
encryption_key = optional(string)
resource_group_id = optional(string)
snapshot_id = optional(string) # set if you would like to base volume on a snapshot
})
)
[] no
boot_volume_encryption_key CRN of boot volume encryption key string null no
boot_volume_snapshot_id The snapshot id of the volume to be used for creating boot volume attachment (if specified, the image_id parameter will not be used) string null no
create_security_group Create security group for VSI. If this is passed as false, the default will be used bool n/a yes
enable_floating_ip Create a floating IP for each virtual server created bool false no
existing_kms_instance_guid The GUID of the Hyper Protect Crypto Services instance in which the key specified in var.boot_volume_encryption_key is coming from. string null no
image_id Image ID used for VSI. Run 'ibmcloud is images' to find available images in a region string n/a yes
kms_encryption_enabled Set this to true to control the encryption keys used to encrypt the data that for the block storage volumes for VPC. If set to false, the data is encrypted by using randomly generated keys. For more info on encrypting block storage volumes, see https://cloud.ibm.com/docs/vpc?topic=vpc-creating-instances-byok bool false no
load_balancers Load balancers to add to VSI
list(
object({
name = string
type = string
listener_port = optional(number)
listener_port_max = optional(number)
listener_port_min = optional(number)
listener_protocol = string
connection_limit = optional(number)
idle_connection_timeout = optional(number)
algorithm = string
protocol = string
health_delay = number
health_retries = number
health_timeout = number
health_type = string
pool_member_port = string
profile = optional(string)
accept_proxy_protocol = optional(bool)
subnet_id_to_provision_nlb = optional(string) # Required for Network Load Balancer. If no value is provided, the first one from the VPC subnet list will be selected.
dns = optional(
object({
instance_crn = string
zone_id = string
})
)
security_group = optional(
object({
name = string
rules = list(
object({
name = string
direction = string
source = string
tcp = optional(
object({
port_max = number
port_min = number
})
)
udp = optional(
object({
port_max = number
port_min = number
})
)
icmp = optional(
object({
type = number
code = number
})
)
})
)
})
)
})
)
[] no
machine_type VSI machine type. Run 'ibmcloud is instance-profiles' to get a list of regional profiles string n/a yes
manage_reserved_ips Set to true if you want this terraform module to manage the reserved IP addresses that are assigned to VSI instances. If this option is enabled, when any VSI is recreated it should retain its original IP. bool false no
placement_group_id Unique Identifier of the Placement Group for restricting the placement of the instance, default behaviour is placement on any host string null no
prefix The IBM Cloud platform API key needed to deploy IAM enabled resources string n/a yes
resource_group_id ID of resource group to create VSI and block storage volumes. If you wish to create the block storage volumes in a different resource group, you can optionally set that directly in the 'block_storage_volumes' variable. string n/a yes
secondary_allow_ip_spoofing Allow IP spoofing on additional network interfaces bool false no
secondary_floating_ips List of secondary interfaces to add floating ips list(string) [] no
secondary_security_groups The security group IDs to add to the VSI deployment secondary interfaces (5 maximum). Use the same value for interface_name as for name in secondary_subnets to avoid applying the default VPC security group on the secondary network interface.
list(
object({
security_group_id = string
interface_name = string
})
)
[] no
secondary_subnets List of secondary network interfaces to add to vsi secondary subnets must be in the same zone as VSI. This is only recommended for use with a deployment of 1 VSI.
list(
object({
name = string
id = string
zone = string
cidr = optional(string)
})
)
[] no
secondary_use_vsi_security_group Use the security group created by this module in the secondary interface bool false no
security_group Security group created for VSI
object({
name = string
rules = list(
object({
name = string
direction = string
source = string
tcp = optional(
object({
port_max = number
port_min = number
})
)
udp = optional(
object({
port_max = number
port_min = number
})
)
icmp = optional(
object({
type = number
code = number
})
)
})
)
})
null no
security_group_ids IDs of additional security groups to be added to VSI deployment primary interface. A VSI interface can have a maximum of 5 security groups. list(string) [] no
skip_iam_authorization_policy Set to true to skip the creation of an IAM authorization policy that permits all Storage Blocks to read the encryption key from the KMS instance. If set to false, pass in a value for the KMS instance in the existing_kms_instance_guid variable. In addition, no policy is created if var.kms_encryption_enabled is set to false. bool false no
snapshot_consistency_group_id The snapshot consistency group Id. If supplied, the group will be queried for snapshots that are matched with both boot volume and attached (attached are matched based on name suffix). You can override specific snapshot Ids by setting the appropriate input variables as well. string null no
ssh_key_ids ssh key ids to use in creating vsi list(string) n/a yes
subnets A list of subnet IDs where VSI will be deployed
list(
object({
name = string
id = string
zone = string
cidr = optional(string)
})
)
n/a yes
tags List of tags to apply to resources created by this module. list(string) [] no
use_static_boot_volume_name Sets the boot volume name for each VSI to a static name in the format {hostname}_boot, instead of a random name. Set this to true to have a consistent boot volume name even when VSIs are recreated. bool false no
user_data User data to initialize VSI deployment string n/a yes
vpc_id ID of VPC string n/a yes
vsi_per_subnet Number of VSI instances for each subnet number n/a yes

Outputs

Name Description
consistency_group_boot_snapshot_id The Snapshot Id used for the VSI boot volume, determined from an optionally supplied consistency group
consistency_group_storage_snapshot_ids Map of attached storage volumes requested, and the Snapshot Ids that will be used, determined from an optionally supplied consistency group, and mapped
fip_list A list of VSI with name, id, zone, and primary ipv4 address, and floating IP. This list only contains instances with a floating IP attached.
ids The IDs of the VSI
lb_hostnames Hostnames for the Load Balancer created
lb_security_groups Load Balancer security groups
list A list of VSI with name, id, zone, and primary ipv4 address
vsi_security_group Security group for the VSI

Contributing

You can report issues and request features for this module in GitHub issues in the module repo. See Report an issue or request a feature.

To set up your local development environment, see Local development setup in the project documentation.