We will exemplify by deploying to the EWC site running on EUMETSAT's infrastructure. However, note steps described in this guide are valid for deployment on the ECMWF site as well. |
You can deploy Items from the EWC Community Hub to provision cloud resources such as compute instances, networking, and storage. This guide shows just one of many use-cases. We will deploy an Item of Technology "Terraform Module", namely the OpenStack Compute Instance Item, to 1) create an Ubuntu 24.04 VM, 2) safely modify its attachments (public IP, additional disk, GPU), 3) clean everything up afterwards.
OpenStack Application Credentials: To authorize the creation of the compute instance itself:
SSH access: In this example, by impersonating the default Linux account of EWC's Ubuntu VM images via a valid SSH keypair:
EWC Documentation look up for image_name
and flavor_name
supported on your deployment site:
Work environment equipped with:
You can verify versions installed in your workspace with:
$ git --version |
$ terraform --version |
$ python4 --version |
If any of the above raises an error, or the version is older than recommended, install/update via your package manager of preference. You can also follow thee official Terraform documentation for OS-specific installation steps.
Find the Item's detail page on the EWC Community Hub Dashboard by visiting https://www.europeanweather.cloud/community-hub/openstack-compute-instance-terraform-module. Note that, as of Sep. 10th, 2025, the latest version of the Item is 1.4.0.
By clicking on the "Repository" button, you'll get redirected to GitHub. Use the command documented on the home of the repository to clone it to your local work environment. In this example, we run:
$ git clone https://github.com/ewcloud/ewc-tf-module-openstack-compute.git |
Navigate to the root directory of the Item's source:
$ cd ewc-tf-module-openstack-compute |
Then checkout the correct version of the code to ensure you deploy vetted functionality:
$ git checkout 1.4.0 |
Terraform must authenticate against EWC's OpenStack API. If you lack credentials, follow these steps to request them.
With your credentials file at hand, export its content as environmental variables within your workspace, in the same way you would if you were using the OpenStack CLI.
Change one directory above the the root directory of the Item's source, and create a main.tf
file describing the VM you want to provision.
$ cd ../ && touch main.tf |
As for the contents of the file, take the example below, making sure to replace the contents of the key-value input pairs defined within locals
:
# main.tf locals { keypair_name = "john-cloudy-publickey" virtual_image = "ubuntu-24.04-20250604102601" plan = "vm.a6000.1" app_name = "demo" instance_name = "john-cloudy" instance_index = 1 private_networks = ["private"] external_network = "external" ecurity_groups = ["default"] instance_has_fip = true extra_volume = true extra_volume_size = 512 extra_volume2 = true extra_volume2_size = 512 tags = { environment = "production" owner = "john-cloudy" deployment-tool = "terraform" } } terraform { required_version = ">= 0.14.0" required_providers { openstack = { source = "terraform-provider-openstack/openstack" version = "~> 1.53.0" } } } data "openstack_images_image_v2" "image" { name = local.virtual_image most_recent = true } data "openstack_compute_flavor_v2" "flavor" { name = local.plan } module "instance" { source = "./ewc-tf-module-openstack-compute" app_name = local.app_name instance_name = local.instance_name instance_index = local.instance_index image_id = data.openstack_images_image_v2.image.id flavor_id = data.openstack_compute_flavor_v2.flavor.id keypair_name = local.keypair_name networks = local.private_networks instance_has_fip = local.instance_has_fip extra_volume = local.extra_volume extra_volume_size = local.extra_volume_size extra_volume2 = local.extra_volume2 extra_volume2_size = local.extra_volume2_size security_groups = local.security_groups external_network_name = local.external_network tags = local.tags } |
Initialize and apply:
$ terraform init |
$ terraform plan |
$ terraform apply |
Confirm when prompted to accept infrastructure changes by typing yes
.
Compute instance provisioning may take 5–15 minutes. Upon successful completion, you will see an execution summary listing the seven added resources:
module.instance.openstack_compute_floatingip_associate_v2.fip[0]: Creation complete after 3s [id=188.115.7.131/fd933397-af69-442b-8a5a-4ac808e2f352/10.0.0.50] module.instance.openstack_compute_volume_attach_v2.volume_attachment[0]: Creation complete after 5s [id=fd933397-af69-442b-8a5a-4ac808e2f352/e90ca837-8ed9-47c7-8509-5dc62e14ea65] module.instance.openstack_compute_volume_attach_v2.volume_attachment2[0]: Creation complete after 5s [id=fd933397-af69-442b-8a5a-4ac808e2f352/1201e3b3-0134-43a1-8ccc-85692ab76038] Apply complete! Resources: 7 added, 0 changed, 0 destroyed. |
At this point, you can test out the access by SSH-ing into the VM. You can get the floating IP address is included in the execution summary above. Furthermore, assuming our private key is available at the path ~/.ssh/id_rsa
, (counter part to the public one registered in EWC as john-cloudy-publickey
), we can test access by running ssh -T
(-T
for test). In this example, the full command would be:
$ ssh -T ubuntu@188.115.7.131 -i ~/.ssh/id_rsa |
As is the case for other Items open-sourced by the EWC, you can change the inputs of the OpenStack Compute Terraform Module at any point in time, by simply re-running with the new values. Picture for following user-journey:
After having provisioned the VM, you run some Ansible Playbook from your local work environment to install specialized software onto the new VM (i.e. EUMETSAT Data Tailor Flavour). You then realize that having two additional disks attached to the VM is unnecessary, and for the sake of security, you'd better not allow any network traffic from the public internet.
To achieve this change, you can simply edit the main.tf
file, namely disabling the floating IP address and the second extra volume:
locals { # Some untouched customizations ... instance_has_fip = false # More untouched customizations ... extra_volume2 = false # ... } |
In our example, the resulting customization would look like:
main.tf (no public internet, no 2nd extra volume) locals { keypair_name = "john-cloudy-publickey" virtual_image = "ubuntu-24.04-20250604102601" plan = "vm.a6000.1" app_name = "demo" instance_name = "john-cloudy" instance_index = 1 private_networks = ["private"] external_network = "external" ecurity_groups = ["default"] instance_has_fip = false extra_volume = true extra_volume_size = 512 extra_volume2 = false extra_volume2_size = 512 tags = { environment = "production" owner = "john-cloudy" deployment-tool = "terraform" } } terraform { required_version = ">= 0.14.0" required_providers { openstack = { source = "terraform-provider-openstack/openstack" version = "~> 1.53.0" } } } data "openstack_images_image_v2" "image" { name = local.virtual_image most_recent = true } data "openstack_compute_flavor_v2" "flavor" { name = local.plan } module "instance" { source = "./ewc-tf-module-openstack-compute" app_name = local.app_name instance_name = local.instance_name instance_index = local.instance_index image_id = data.openstack_images_image_v2.image.id flavor_id = data.openstack_compute_flavor_v2.flavor.id keypair_name = local.keypair_name networks = local.private_networks instance_has_fip = local.instance_has_fip extra_volume = local.extra_volume extra_volume_size = local.extra_volume_size extra_volume2 = local.extra_volume2 extra_volume2_size = local.extra_volume2_size security_groups = local.security_groups external_network_name = local.external_network tags = local.tags } |
To apply the changes, simply run:
$ terraform apply --auto-approve |
If successfully completed, the execution summary will list four resources (out of the initial seven) as destroyed:
module.instance.openstack_networking_floatingip_v2.fip[0]: Destruction complete after 8s module.instance.openstack_blockstorage_volume_v3.instance_volume2[0]: Still destroying... [id=1201e3b3-0134-43a1-8ccc-85692ab76038, 00m10s elapsed] module.instance.openstack_blockstorage_volume_v3.instance_volume2[0]: Destruction complete after 10s Apply complete! Resources: 0 added, 0 changed, 4 destroyed. |
Optional but recommended; cleaning up any unused infrastructure its a chore, sometimes time-consuming, but important nontheless.
Luckily, deleting Terraform-managed infrastructure is easy. While still on the same directory as the main.tf
file you previously created, run:
$ terraform apply --destroy |
You will be prompted for confirmation. Make sure the resources listed for destruction are indeed related to your VM. Confirm to accept changes by typing yes
.
All done! You now equipped to provision and teardown cloud infrastructure with a full-managed state, using nothing but the Community Hub and a couple of commands 🎉.
main.tf
for reproducibility.terraform plan
before every apply.tags = {…}
) for easier costs traceability and administration.main.tf
you created, as well as the terraform.tfstate
file that resulted from the execution, using git, to avoid loosing track of your the resources' state.Checkout the troubleshooting documentation of the Item for information on common problems and how to troubleshoot them. For unresolved issues, check the GitHub issues for a similar problem, ask the community on the peer support channel of the EWC discussion platform. You may also place a tickets at EWC Support Portal when dealing with EWC open-sourced Items.