Recommendation

It is strongly recommended that you visit the pages in Examples of Terraform for Jetstream2 in order

To begin constructing your Jetstream2 Terraform configuration, download the file securitygroup.tf into your configuration folder. You must also initialize the environment variables that Terraform's OpenStack provider uses when connecting to Jetstream2. To do so, substitute the exact name of your openrc.sh file into a command like source openrc.sh. When that's done, let's look at the contents of securitygroup.tf:


resource "openstack_networking_secgroup_v2" "ssh_ping" {
  name        = "terratest_sec_grp"
  description = "Security group with SSH and Ping opened"
}

# For SSH
resource "openstack_networking_secgroup_rule_v2" "ssh_rule" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 22
  port_range_max    = 22
  remote_ip_prefix  = "0.0.0.0/0"
  security_group_id = openstack_networking_secgroup_v2.ssh_ping.id
}

# For Ping
resource "openstack_networking_secgroup_rule_v2" "ping_rule" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "icmp"
  remote_ip_prefix  = "0.0.0.0/0"
  security_group_id = openstack_networking_secgroup_v2.ssh_ping.id
}

The HashiCorp Configuration Language (HCL) allows you to create configurations as a set of "arguments" and "blocks". Arguments assign a value to a particular name, and blocks are structures that contain other content. Our file contains three top-level resource blocks, which of each contain arguments. This example does not have any resource blocks containing subsidiary blocks. Comments in .tf files can begin with "#" or "//" and run through the end of the line, or they can use "/*" and "*/" to bracket sections of text.

Terraform provides style conventions that you may want to follow when writing your configuration scripts. This topic also uses "best practice" naming conventions from the Terraform user community when naming Terraform resources. Those suggestions include:

  • Names should only use lower case letters, numbers and the underscore character.
  • Names should not repeat the resource type, but instead describe its purpose or characteristics.
  • If a resource is the only one of its type and needn't be described, it should be named "this".

Resource Blocks

In the Terraform initialization page we saw examples of terraform and provider blocks. The blocks on this page are of the most common type: resource (we will introduce a few other block types in the pages to come). The syntax of a resource block takes the form:


resource RESOURCE_TYPE RESOURCE_NAME { OTHER_CONTENT }

In our code, the first resource is of type "openstack_networking_secgroup_v2" and we will be referring to it within our configuration by the name "ssh_ping". The block type must exactly match the name of a known resource type from a provider. These types can be found in Terraform's provider registry, and this security group type is documented there.

If you are familiar with the OpenStack API, you can easily decode the name of this resource type: it is the "security group" object as defined in "version 2" of OpenStack's "networking" API. Similarly, the other two resources in the file are "security group rule"" objects from the same API. The body of the security group resource contains some HCL "arguments" that are assigned constant values. For example, the "name" argument specifies the name that the security group will have in your OpenStack project.

Each security group rule block defines several arguments, as specified in the documentation. These rules will allow incoming network traffic from any IP address over TCP on port 22 (for SSH) and over ICMP (for pinging your instances), where no port specification is required. Each block specifies that it is a member of the security group defined at the top of the file, with that resource being referenced by its ID.

Referencing Attribute Values

References to properties of other resources take the form PROVIDER_TYPE.RESOURCE_NAME.PROPERTY_NAME. Using references like these allows you to define a set of interdependent resources. Note that it is not necessary to define interdependent resources in the same file, or in any particular order. The contents of all Terraform files in the configuration are read before the references are resolved.

Running the Example

Now let's use the Terraform command line interface (CLI) to process this configuration. First, just to see what Terraform thinks it needs to do, issue the command terraform plan. The output in your terminal should show that one security group and two rules will be created. If everything looks good, issue the command to actually make the necessary changes: terraform apply. This command will start by outputing the same text as the "plan" command, and will then ask you if you want to perform the actions. Enter "yes" at the prompt. The command will then display information as it performs the actions and finish by displaying status information.

If the command succeeded, you can visit the Horizon web interface and select the Jetstream2 location you are using, then view your new security group in the "Compute" section. You can also look at the contents of your configuration directory to see that Terraform has saved its understanding of the state of your configuration in the file terraform.tfstate.

 
©  |   Cornell University    |   Center for Advanced Computing    |   Copyright Statement    |   Inclusivity Statement