From 382dbb15914d137d26fb43d0a6c7637ff5e31a0d Mon Sep 17 00:00:00 2001 From: Marco Emilio Poleggi <marco-emilio.poleggi@hesge.ch> Date: Thu, 29 Sep 2022 14:28:02 +0200 Subject: [PATCH] Done lab refactoring on OpenStack --- SwitchEngines/README.md | 328 +++++++++++++++++------- SwitchEngines/conf/clouds.yaml.api_cred | 9 +- SwitchEngines/conf/clouds.yaml.app_cred | 10 +- SwitchEngines/main.tf.advnc | Bin 1509 -> 2450 bytes SwitchEngines/main.tf.basic | 32 +-- SwitchEngines/outputs.tf | Bin 290 -> 122 bytes SwitchEngines/scripts/add-ssh.yaml | 16 ++ SwitchEngines/variables.tf | 6 + 8 files changed, 270 insertions(+), 131 deletions(-) create mode 100644 SwitchEngines/scripts/add-ssh.yaml create mode 100644 SwitchEngines/variables.tf diff --git a/SwitchEngines/README.md b/SwitchEngines/README.md index 039df97..2265f49 100644 --- a/SwitchEngines/README.md +++ b/SwitchEngines/README.md @@ -41,31 +41,29 @@ Please, refer to your OS documentation for the proper way to do so v1.1.4. Skip the TF "Quick start tutorial" (Docker). 1. [OpenStack CLI](https://docs.openstack.org/newton/user-guide/common/cli-install-openstack-command-line-clients.html) - version >= 5.7.0. It is recommended to install your original distribution + version >= 6.0.0. It is recommended to install your original distribution package named like `python-openstackclient`. - 1. Grab or create a new project in your OpenStack account. The placeholder - used in this exercise is `<your-project-name>` with value `Cloud-MA-IaC`. - 1. On the OpenStack Horizon dashboard, go to your project page, then - 1. create new [Application + 1. On the OpenStack dashboard, create a new project. The placeholder used in + this exercise is `<your-project-name>` with value `Cloud-MA-IaC`. + 1. Go to your project page, then create new [Application Credentials](https://engines.switch.ch/horizon/identity/application_credentials/) - and save it as `~/.config/openstack/clouds.yaml`. With SwitchEngines, the - cloud name to use for this is `engines`. :warning: App credentials might - not work for some commands. A template is also available in repo file - [`conf/clouds.yaml.api_cred`](conf/clouds.yaml.api_cred). Alternatively, + and save it as `~/.config/openstack/clouds.yaml`. With SwitchEngines, + the cloud name to use for this is `engines`. :warning: App credentials + might not work for some commands. A template is also available in this + repo file + [`conf/clouds.yaml.app_cred`](conf/clouds.yaml.app_cred). Alternatively, you can use your [API credentials](https://engines.switch.ch/horizon/project/api_access/clouds.yaml) - with explicit project name/ID -- you'll have to add your API `password` from - your profile page's ["Credentials" + with explicit project name/ID -- you'll have to add your API + `password` from your profile page's ["Credentials" tab](https://engines.admin.switch.ch/users/profile). A template is - available in repo file - [`conf/clouds.yaml.app_cred`](conf/clouds.yaml.app_cred). - <!-- 1. download your [RC --> - <!-- file](https://engines.switch.ch/horizon/project/api_access/openrc/) and --> - <!-- install it (it asks for your API password): --> - <!-- ``` shell --> - <!-- $ source <your-project>-openrc.sh --> - <!-- ``` --> - 1. Verify that your credentials are OK (:warning: it might reveal secrets!): + available in this repo file + [`conf/clouds.yaml.api_cred`](conf/clouds.yaml.app_cred). :warning: + Avoid mixing different authentication schemes in `clouds.yaml` or from + the environment (via sourcing so called OpenStack RC files). + 1. Verify that your credentials are OK (:warning: it might reveal secrets! + If you have just one cloud configured, you can drop the switch + `--os-cloud=engines`, else adapt accordingly): ``` shell lcl$ $ openstack --os-cloud=engines [application] credential list ``` @@ -74,7 +72,7 @@ Please, refer to your OS documentation for the proper way to do so **Goal:** instruct TF to handle a single OpenStack instance. -<a name="image-query"></a>Find out the smallest image to use for a Debian server: +Find out the smallest image to use for a Debian server: ``` shell lcl$ openstack --os-cloud=engines image list --public --status=active --sort-column=Size -c ID -c Name -c Size --long @@ -86,7 +84,7 @@ lcl$ openstack --os-cloud=engines image list --public --status=active --sort-col ``` :bulb: We use the first ID found for the placeholder `<your-image-ID>`. In -SwitchEngines this is 1.5GB. +SwitchEngines, that has a size of ~1.5GB. Find out the smallest instance *flavor* that acommodates our Debian image. @@ -106,6 +104,9 @@ Create a "sandbox" directory on your local machine in HCL language), the infrastructure *definition* file, with the following content (replace all `<...>` tokens with actual values): +:bulb: Application credentials shall match those in file +`~/.config/openstack/clouds.yaml`. + ``` hcl terraform { required_version = ">= 0.14.9" @@ -122,7 +123,7 @@ provider "openstack" { project_domain_id = "<your-project-ID>" application_credential_id = "<your-app-cred-ID>" application_credential_secret = "<your-app-cred-secret>" - region = "ZH" + region = "<your-region>" } resource "openstack_compute_instance_v2" "app_server" { @@ -229,8 +230,7 @@ Do you want to perform these actions? Enter a value: yes -openstack_compute_instance_v2.app_server: Creating... -openstack_compute_instance_v2.app_server: Still creating... [10s elapsed] +... openstack_compute_instance_v2.app_server: Creation complete after 18s [id=f70aef53-51f9-4d12-a4a9-fe9a6cc5a58f] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. @@ -295,7 +295,7 @@ not, why? We'll deal with that in Task #4 below. Now, stop the running instance (its ID is shown above ;-): ``` shell -lcl$ $ openstack server stop f70aef53-51f9-4d12-a4a9-fe9a6cc5a58f +lcl$ openstack --os-cloud=engines server stop f70aef53-51f9-4d12-a4a9-fe9a6cc5a58f ``` wait some seconds and test again: @@ -310,114 +310,254 @@ resource. So, let's refresh it, and check again: ``` shell lcl$ terraform refresh -aws_instance.app_server: Refreshing state... [id=i-0155ba9d77ee0a854] -lcl$ terraform show | grep instance_state - instance_state = "stopped" +... +lcl$ terraform show | grep power_state + power_state = "shutoff" ``` Ah-ha! +Hold on a second: our TF plan does not (explicitly) specify the desired status +of a resource. What happens if we reapply the plan? Lets' try: -### Task #4: change your infrastructure ### +``` shell +lcl$ terraform apply -auto-approve +openstack_compute_instance_v2.app_server: Refreshing state... [id=...] +... +Terraform will perform the following actions: +... + ~ power_state = "shutoff" -> "active" +... +Apply complete! Resources: 0 added, 1 changed, 0 destroyed. -Indeed, the instance doesn't have a (floating) *public* IP address, so we need -to get one and associate it to our instance with the following snippet added -to `main.tf`: +lcl$ terraform show | grep power_state + power_state = "active" +``` -``` hcl -resource "openstack_networking_floatingip_v2" "fip_1" { - pool = "public" -} +:warning: Apply was run in `-auto-approve` (non interactive) mode which +assumes "yes" to all questions. Use with care! + +From the above commands' output we see that + * the local state is refreshed before doing anything, + * 1 change was applied: the instance has been switched on, + * OpenStack instances have an "active" default `power_state` :-) -resource "openstack_compute_floatingip_associate_v2" "fip_1" { - # we use var/obj notation here ${x.y} - floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" - instance_id = "${openstack_compute_instance_v2.app_server.id}" - # to avoid getting "Resource not found" - wait_until_associated = true -} -``` -Let's see what happens: +### Task #4: change your infrastructure ### + +**Goal:** modify the resource created before, and learn how to apply changes +to a Terraform project. + +Replace the resource's `image_id` in `main.tf` with the second one found from +the catalog query done above -- it should be a "Debian Bullseye 11 +(SWITCHengines)". Before applying our new plan, let's see what TF thinks of +it: + ``` shell -lcl$ terraform apply -auto-approve -openstack_compute_instance_v2.app_server: Refreshing state... [id=f70aef53-51f9-4d12-a4a9-fe9a6cc5a58f] -... +lcl$ terraform plan -out=change-image-ID.tfplan +openstack_compute_instance_v2.app_server: Refreshing state... [id=1edad9e2-5459-4980-bbc5-a0c5b65bfb0d] + Terraform will perform the following actions: - # openstack_compute_floatingip_associate_v2.fip_1 will be created - + resource "openstack_compute_floatingip_associate_v2" "fip_1" { - + floating_ip = (known after apply) - ... - } + # openstack_compute_instance_v2.app_server will be updated in-place + ~ resource "openstack_compute_instance_v2" "app_server" { + id = "1edad9e2-5459-4980-bbc5-a0c5b65bfb0d" + ~ image_id = "8674f1a5-f7d9-4975-af0b-d2e9e33c9152" -> "54ee4d6e-9155-4698-ab2b-45d9067e8e8e" + name = "TF-managed" + tags = [] + # (13 unchanged attributes hidden) - # openstack_networking_floatingip_v2.fip_1 will be created - + resource "openstack_networking_floatingip_v2" "fip_1" { - + address = (known after apply) - ... + # (1 unchanged block hidden) } -Plan: 2 to add, 0 to change, 0 to destroy. -openstack_networking_floatingip_v2.fip_1: Creating... -openstack_networking_floatingip_v2.fip_1: Creation complete after 9s [id=81f7690f-e024-4eb8-bbbc-98a242c3b0c3] -openstack_compute_floatingip_associate_v2.fip_1: Creating... -openstack_compute_floatingip_associate_v2.fip_1: Creation complete after 6s [id=86.119.32.210/f70aef53-51f9-4d12-a4a9-fe9a6cc5a58f/] +Plan: 0 to add, 1 to change, 0 to destroy. +... +Saved the plan to: change-image-ID.tfplan + +To perform exactly these actions, run the following command to apply: + terraform apply "change-image-ID.tfplan" ``` -Here we go. First, observe how TF had to refresh its local status before -applying the new plan. Then, now the instance got the public IP address shown -at the bottom of the command's output. However, a last bit is still missing, -because the "default" *security group* only allows outbound traffic. Thus we -need something like: +:bulb: Remarks: + * The change we want to apply is *not* destructive. + * We saved our plan. :question: Why? It is not really necessary in a simple + scenario like ours, however a more complex IaC workflow might require plan + artifacts to be programmatically validated and versioned. + +Apply the saved plan: +``` shell +lcl$ terraform apply change-image-ID.tfplan +$ terraform apply change-image-ID.tfplan +... +Apply complete! Resources: 0 added, 1 changed, 0 destroyed. +``` + +:bulb: What? Not asking for confirmation? Indeed, a *saved* plan is intended for +automated workflows! Moreover, a saved plan will come handy for rolling back a +broken infrastructure to the last working setup. + +:question: What if we did not save our plan, and called a plain apply command? +Would the result be the same? + + +### Task #5: input variables ### + +**Goal:** make a TF plan more flexible via input variables. + +Our original plan has all its content hard-coded. Let's make it more flexible +with some input variables stored in a separate `variables.tf` file inside your +TF sandbox: ``` hcl -resource "openstack_compute_instance_v2" "app_server" { - ... # as above - security_groups = ["default", "secgroup_tf"] +variable "instance_name" { + description = "Value of the instance's name tag" + type = string + default = "AnotherAppServerInstance" } +``` -resource "openstack_networking_secgroup_v2" "secgroup_tf" { - name = "secgroup_tf" -} +Then modify the `main.tf` as follows: -resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_1" { - 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.secgroup_tf.id}" +``` hcl +resource "openstack_compute_instance_v2" "app_server" { + ... + metadata = { + my_instance_name = var.instance_name + } } +``` -resource "openstack_networking_floatingip_v2" "fip_1" ... +Apply the changes: +``` shell +lcl$ terraform apply -auto-approve + +Plan: 0 to add, 1 to change, 0 to destroy. ... +Apply complete! Resources: 0 added, 1 changed, 0 destroyed. ``` -Now, our instance is reachable via SSH (only!). But can we login? The reply is -in Task #7. +You should see the new tag added to the "Metadata" section of the Horizon +dashboard: +`https://engines.switch.ch/horizon/project/instances/<instance-ID>/`. + +:bulb: **Exercise:** input variables can also be passed on the `apply` command +line. Find how to do that with another different value for the variable +`instance_name`. :question: Would this last change be persistent if we rerun a +plain `terraform apply`? -### Task #5: input variables ### ### Task #6: queries with outputs ### -### Task #7: SSH provisioning with Cloud-Init ### +**Goal:** use output values to query a provisioned infrastructure. + +We have seen in the previous tasks that the infrastructure's status can be +displayed via `terraform show`: a rather clumsy way, if you just want to +extract some specific information. A better programmatic way of querying your +infrastructure makes use of "outputs". In your sandbox, put the following in a +file called `outputs.tf`: -@@@@@ OLD part below@@@@ +``` hcl +output "instance_id" { + description = "ID of the instance" + value = openstack_compute_instance_v2.app_server.id +} +``` -Also, prepare a `~/terraform/OpenStack/outputs.tf` file with the appropriate -contents to get the instance's public IP address (via `instance_public_ip`). +We have declared two outputs. As usual with TF, before querying their +associated values, we need to apply the changes: +``` shell +lcl$ terraform apply -auto-approve +... +Apply complete! Resources: 0 added, 0 changed, 0 destroyed. + +Outputs: +instance_id = "93914f14-e521-4cc1-acfe-046bc3fa31be" +``` -Then apply! +So, we already got the needed information, but, within a workflow, it is more +practical to do something like: ``` shell -lcl$ terraform apply +lcl$ terraform output instance_id ``` -Verify that you can SSH as user `debian` into your instance: +:bulb: **Exercise:** Add an output item to display the instance metadata tag +`my_instance_name`. +:question: What if the `my_instance_name` tag is changed outside TF? Try f.i.: ``` shell -lcl$ ssh debian@$(terraform output -raw instance_public_ip) -i ../tf-cloud-init +lcl$ openstack --os-cloud=engines server set \ + --property my_instance_name="Foo-Bar" 93914f14-e521-4cc1-acfe-046bc3fa31be +``` + +:question: What must be done to have TF respect that external change? + +:question: How to revert an external change via TF? + + +### Task #7: networking and SSH provisioning with Cloud-Init ### + +**Goal:** use Cloud-Init to provision an SSH access to your TF-managed +instance. + +Did you try to SSH into the instance you created via TF? It cannot work, +because we did not instructed TF about networking, login, users, keys or +anything else. **This is left entirely to you as an exercise.** With reference +to the official TF documentation for the [OpenStack +provider](https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs/), you shall: + + 1. Destroy your infrastructure. Guess how ;-) + 1. Create an SSH key pair `tf-cloud-init`. + 1. Create a new cloud-init file + `~/terraform/OpenStack/scripts/add-ssh.yaml` with the following content: + ``` yaml + #cloud-config + #^^^^^^^^^^^^ + # DO NOT TOUCH the first line! + --- + groups: + - debian: [root, sys] + - terraform + + users: + - default + - name: terraform + gecos: terraform + primary_group: terraform + groups: users, admin + ssh_authorized_keys: + - <your-SSH-pub-key-on-one-line> + ``` + :warning: **Mind that the first line of this file must spell exactly + `#cloud-config`**! + 1. Modify the `main.tf` as follows: + 1. add a resource block for a custom v2 network *security group*; + 1. add resource blocks for v2 *security group rules* allowing ICMP ping + and TCP ingress ports 22 from anywhere with any egress port open. These + resources shall reference your security group; + 1. add a resource block for a v2 *floating IP* from the public pool; + 1. add a resource block for a v2 *floating IP association* referencing + your floating IP resource and your compute instance resource; + 1. extend your `"app_server"` resource block to: + 1. reference your custom security group as well as the default one, + 1. associate a public IP address, + 1. include the above cloud-init file, + 1. add a TF output `"instance_public_ip"`. + +:bulb: In the above instruction, "reference" means that the keys shall take +values dynamically from variable expansion, like: +``` hcl + key = ${<object.attribute...>} +``` + +When done, *validate* your new plan and *apply* it. Verify that you can ping +and connect via SSH as user `terraform` into your instance: + +``` shell +lcl$ ping $(terraform output -raw instance_public_ip) +... +lcl$ ssh terraform@$(terraform output -raw instance_public_ip) -i /path/to/private/key/tf-cloud-init +... ``` diff --git a/SwitchEngines/conf/clouds.yaml.api_cred b/SwitchEngines/conf/clouds.yaml.api_cred index 32777c9..a07c765 100644 --- a/SwitchEngines/conf/clouds.yaml.api_cred +++ b/SwitchEngines/conf/clouds.yaml.api_cred @@ -1,10 +1,13 @@ -# Project-agnostic -- API credentials +# -*- mode: yaml -*- +# OpenStack conf file with *API* credentials -- +# <https://engines.switch.ch/horizon/project/api_access> clouds: engines: auth: - auth_url: https://keystone.cloud.switch.ch:5000/v3 + auth_url: "https://keystone.cloud.switch.ch:5000/v3" username: "<your-user-name>" - password: "<your-password" + password: "<your-password>" + # project_name: "<your-project>" user_domain_name: "Default" interface: "public" identity_api_version: 3 diff --git a/SwitchEngines/conf/clouds.yaml.app_cred b/SwitchEngines/conf/clouds.yaml.app_cred index 6021f0b..40a5b98 100644 --- a/SwitchEngines/conf/clouds.yaml.app_cred +++ b/SwitchEngines/conf/clouds.yaml.app_cred @@ -1,12 +1,12 @@ -# Project-specific -- application credentials. +# -*- mode: yaml -*- +# OpenStack conf file with *application* credentials. clouds: - Cloud-MA-IaC: + engines: auth: - auth_url: https://keystone.cloud.switch.ch:5000/v3 + auth_url: "https://keystone.cloud.switch.ch:5000/v3" application_credential_id: "<your-app-cred-ID>" application_credential_secret: "<your-app-cred-secret>" - user_domain_name: Default - project_domain_name: Default interface: "public" + region: "<your-region>" identity_api_version: 3 auth_type: "v3applicationcredential" diff --git a/SwitchEngines/main.tf.advnc b/SwitchEngines/main.tf.advnc index c5ace7adaf62c2938ad383b304302acd56fd4f13..d1fe209a99075405e0512e77a60d8307b3b6e30c 100644 GIT binary patch literal 2450 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 literal 1509 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 diff --git a/SwitchEngines/main.tf.basic b/SwitchEngines/main.tf.basic index 3bcab00..e6b5142 100644 --- a/SwitchEngines/main.tf.basic +++ b/SwitchEngines/main.tf.basic @@ -1,12 +1,12 @@ +# -*- mode: terraform -*- terraform { - required_version = ">= 0.14.9" required_providers { openstack = { source = "terraform-provider-openstack/openstack" - # version = "~> 1.35.0" version = "~> 1.48.0" } } + required_version = ">= 0.15.0" } # Configure the OpenStack Provider @@ -15,7 +15,7 @@ provider "openstack" { project_domain_id = "<your-project-ID>" application_credential_id = "<your-app-cred-ID>" application_credential_secret = "<your-app-cred-secret>" - region = "LS" + region = "<your-region>" } resource "openstack_compute_instance_v2" "app_server" { @@ -23,30 +23,4 @@ resource "openstack_compute_instance_v2" "app_server" { image_id = "<your-image-ID>" flavor_name = "<your-flavor>" key_pair = "TF_lab" - security_groups = ["default", "secgroup_tf"] -} - -resource "openstack_networking_secgroup_v2" "secgroup_tf" { - name = "secgroup_tf" -} - -resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_1" { - 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.secgroup_tf.id}" -} - -resource "openstack_networking_floatingip_v2" "fip_1" { - pool = "public" -} - -resource "openstack_compute_floatingip_associate_v2" "fip_1" { - floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" - instance_id = "${openstack_compute_instance_v2.app_server.id}" - # to avoid getting "Resource not found" - wait_until_associated = true } diff --git a/SwitchEngines/outputs.tf b/SwitchEngines/outputs.tf index 87c3f8461141a6cc8e49d008c9acb3229e799c16..0019196b6f6cbdf52fec3bb2055c8685cfa26627 100644 GIT binary patch literal 122 zcmc~VEh#81QBcavD=taQOHPf?Oi@y(=2B2dNi9w;$}A|!%+FJ>RZ#MDQOHkID9K1w zfT>jCQcx&M%qdM(fB;*C{DM@FDaqOK$@#ejr6sBHFtzbzMtX?_1@XnHMP;c)dYLI) GwOjz~WGSrx literal 290 zcmZQ@_Y83kiVO&0h<kqLb?lTHo-nJahxt~Vew}??^YhGiGu_|v9WG5bF%powck<@n zn7>oY=d??6=g7BxH(~IpW2w<z{WQ8|&8}@Twf9Qw-6EC$=u7ex{<Cj&RXo_3TWg<1 zhrIi>NOp7O^3tpoi&FGW4Js;4XP9(f`(m{sVU8*L@hu0{H|+^5(g@RGQ0e#LGd}x9 z%2joKsO`cvhA+-c`=DXX_)o!UfAF%T3%SdGZ!_>o-u~S#W#_`#n`Y_we0pf;%$>B! zb!qs2gUq!F%1cBof4nM-x$hzRA!xb(g|j}JkM9g_WD{~N;7d~5_?vP2U!{d<Yae)9 zH9vW>HdI7|VRh)^D>fI*nvClAD>f#HUfZ($Y+kge_0`7cZOZ;D<L-DoTt3GJ00tF` Al>h($ diff --git a/SwitchEngines/scripts/add-ssh.yaml b/SwitchEngines/scripts/add-ssh.yaml new file mode 100644 index 0000000..88c19b1 --- /dev/null +++ b/SwitchEngines/scripts/add-ssh.yaml @@ -0,0 +1,16 @@ +#cloud-config +#^^^^^^^^^^^^ +# DO NOT TOUCH the first line! +--- +groups: + - debian: [root, sys] + - terraform + +users: + - default + - name: terraform + gecos: terraform + primary_group: terraform + groups: users, admin + ssh_authorized_keys: + - <your-SSH-pub-key-on-one-line> diff --git a/SwitchEngines/variables.tf b/SwitchEngines/variables.tf new file mode 100644 index 0000000..7f6dfe5 --- /dev/null +++ b/SwitchEngines/variables.tf @@ -0,0 +1,6 @@ +# -*- mode: terraform -*- +variable "instance_name" { + description = "Value of the instance's name tag" + type = string + default = "TF-Lab-AppServerInstance" +} -- GitLab