diff --git a/SwitchEngines/README.md b/SwitchEngines/README.md index a192ad70019f42bd02a8ba5e0eca6b8fc6c19939..039df9774923ceca2405e293b8e9dfd8d8f55bcc 100644 --- a/SwitchEngines/README.md +++ b/SwitchEngines/README.md @@ -45,21 +45,27 @@ Please, refer to your OS documentation for the proper way to do so 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, + 1. On the OpenStack Horizon dashboard, go to your project page, then 1. 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). Once created, - 1. 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 `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. Verify that your credentials are OK (:warning: it will reveal secrets!): + 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, + 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" + 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!): ``` shell lcl$ $ openstack --os-cloud=engines [application] credential list ``` @@ -85,7 +91,7 @@ SwitchEngines this is 1.5GB. Find out the smallest instance *flavor* that acommodates our Debian image. ``` shell - lcl$ openstack --os-cloud=Cloud-MA-IaC flavor list --sort-column=RAM --sort-column=Disk --min-disk=5 --min-ram=1024 --limit=1 --public + lcl$ openstack --os-cloud=engines flavor list --sort-column=RAM --sort-column=Disk --min-disk=5 --min-ram=1024 --limit=1 --public +----+----------+------+------+-----------+-------+-----------+ | ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public | +----+----------+------+------+-----------+-------+-----------+ @@ -284,11 +290,118 @@ instance IP's address. Indeed, there is a kind of *digital twin* stored inside the file `terraform.tfstate`. :question: Is that instance accessible from the internet? Give it a try. If -not, why? +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 +``` + +wait some seconds and test again: + +``` shell +lcl$ terraform show | grep power_state + power_state = "active" +``` + +How come? We just discovered that TF read only the local status of a +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" +``` + +Ah-ha! + + +### Task #4: change your infrastructure ### Indeed, the instance doesn't have a (floating) *public* IP address, so we need -to associate one: +to get one and associate it to our instance with the following snippet added +to `main.tf`: + +``` hcl +resource "openstack_networking_floatingip_v2" "fip_1" { + pool = "public" +} + +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: +``` shell +lcl$ terraform apply -auto-approve +openstack_compute_instance_v2.app_server: Refreshing state... [id=f70aef53-51f9-4d12-a4a9-fe9a6cc5a58f] +... +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_networking_floatingip_v2.fip_1 will be created + + resource "openstack_networking_floatingip_v2" "fip_1" { + + address = (known after apply) + ... + } + +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/] +``` + +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: + +``` hcl +resource "openstack_compute_instance_v2" "app_server" { + ... # as above + 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" ... +... +``` + +Now, our instance is reachable via SSH (only!). But can we login? The reply is +in Task #7. + +### Task #5: input variables ### + +### Task #6: queries with outputs ### +### Task #7: SSH provisioning with Cloud-Init ### @@@@@ OLD part below@@@@