{"id":2257,"date":"2018-11-06T11:28:24","date_gmt":"2018-11-06T09:28:24","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/get-started-terraform\/"},"modified":"2018-11-06T11:28:24","modified_gmt":"2018-11-06T09:28:24","slug":"get-started-terraform","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/get-started-terraform\/","title":{"rendered":"How to get started with Terraform"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/upcloud.com\/global\/blog\/upcloud-verified-terraform-provider\/\">Terraform<\/a> is a simple yet powerful open-source infrastructure management tool developed by HashiCorp. It allows you to safely and predictably manage your infrastructure by codifying APIs into declarative configuration files.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/upcloud.com\/media\/terraform_logo.png\" alt=\"Terraform logo\" class=\"wp-image-6158\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">In this guide, we will show you how to install the required software and get started with Terraform on UpCloud. Below, you can find the instructions suitable for most Linux distributions, but Terraform is also available for download on macOS and Windows.<\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Installing Terraform<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Terraform works as a command-line utility that communicates with the supported services via APIs. Installing Terraform on your computer provides you with all the tools you need to manage your infrastructure in the cloud.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Start by heading to the <a href=\"https:\/\/developer.hashicorp.com\/terraform\/downloads\" target=\"_blank\" rel=\"noreferrer noopener\">Terraform installation page<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Select your operating system to find the appropriate installation instructions. E.g. using Ubuntu or Debian:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">wget -O- https:\/\/apt.releases.hashicorp.com\/gpg | sudo gpg --dearmor -o \/usr\/share\/keyrings\/hashicorp-archive-keyring.gpg<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">echo \"deb [signed-by=\/usr\/share\/keyrings\/hashicorp-archive-keyring.gpg] https:\/\/apt.releases.hashicorp.com $(lsb_release -cs) main\" | sudo tee \/etc\/apt\/sources.list.d\/hashicorp.list<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">sudo apt update &amp;&amp; sudo apt install terraform<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once installed, test that Terraform is accessible by checking for the version number in a terminal with the command underneath.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform -v\nTerraform v1.4.5<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is it for Terraform itself. Next, continue below with the instructions for installing the prerequisites and the UpCloud provider plugin for Terraform.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/signup.upcloud.com\/\">Test Terraform on UpCloud!<\/a><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Setting up UpCloud user credentials<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Deploying servers to your UpCloud account requires you to have your username and password safely stored in your environmental variables. Use the commands below to include an account name and password in your profile. Replace the <tt>username<\/tt>&nbsp;and&nbsp;<tt>password<\/tt>&nbsp;with your UpCloud account username and password.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">echo 'export UPCLOUD_USERNAME=<span style=\"color: #ff0000;\">username<\/span>' | tee -a ~\/.bashrc\necho 'export UPCLOUD_PASSWORD=<span style=\"color: #ff0000;\">password<\/span>' | tee -a ~\/.bashrc<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">We recommend you create a new workspace member for API access. Find out more about <a rel=\"noopener\" href=\"https:\/\/upcloud.com\/global\/community\/tutorials\/ \/getting-started-upcloud-api\/\" target=\"_blank\">how to do this at our API tutorial<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then reload the profile to apply the new additions.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">source ~\/.bashrc<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Afterwards, continue below to start your first Terraform project.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Initialising new Terraform project<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Each Terraform project is organised in its own directories. When invoking any command that loads the Terraform configuration, Terraform loads all configuration files within the working directory in alphabetical order. This is important to remember when configuring resources that might be dependent on one another.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a new directory for your Terraform project and change into it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">mkdir -p&nbsp;~\/terraform\/base &amp;&amp; cd ~\/terraform\/base<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Deploying Cloud Servers on UpCloud using Terraform works using the <a href=\"https:\/\/registry.terraform.io\/providers\/UpCloudLtd\/upcloud\/latest\" target=\"_blank\" rel=\"noopener\">verified provider module<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To start with using the UpCloud Terraform module requires you to declare the following configuration block. A standard name for a file with the following HCL is version.tf. Create the file with the below command then open it for editing with your preferred text editor.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">touch version.tf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Next, add the following to the file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">terraform {\n  required_providers {\n    upcloud = {\n      source = \"UpCloudLtd\/upcloud\"\n    }\n  }\n}\n\nprovider \"upcloud\" {\n  # Your UpCloud credentials are read from the environment variables\n  # export UPCLOUD_USERNAME=\"Username for Upcloud API user\"\n  # export UPCLOUD_PASSWORD=\"Password for Upcloud API user\"\n  # Optional configuration settings can be depclared here\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Afterwards, save the file and exit the editor. With the required module declaration in place, you can get started.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, to begin a new configuration, every Terraform project directory needs to be initialised, do this by running the command below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">terraform init<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Terraform sets up the directory to support deploying plans. You should see something like the example output below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Initializing the backend...\n\nInitializing provider plugins...\n- Finding latest version of upcloudltd\/upcloud...\n- Installing upcloudltd\/upcloud v2.1.0...\n- Installed upcloudltd\/upcloud v2.1.0 (self-signed, key ID 60B4E1988F222907)\n\nPartner and community providers are signed by their developers.\nIf you'd like to know more about provider signing, you can read about it here:\nhttps:\/\/www.terraform.io\/docs\/plugins\/signing.html\n\nTerraform has created a lock file .terraform.lock.hcl to record the provider\nselections it made above. Include this file in your version control repository\nso that Terraform can guarantee to make the same selections by default when\nyou run \"terraform init\" in the future.\n\n<span style=\"color: #26a269;\"><span style=\"color: #33da7a;\"><strong>Terraform has been successfully initialized!<\/strong><\/span>\n\nYou may now begin working with Terraform. Try running \"terraform plan\" to see\nany changes that are required for your infrastructure. All Terraform commands\nshould now work.\n\nIf you ever set or change modules or backend configuration for Terraform,\nrerun this command to reinitialize your working directory. If you forget, other\ncommands will detect it and remind you to do so if necessary.\n<\/span><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The initialisation process creates a directory for the plugins in your Terraform folder under <tt>.terraform\/providers<\/tt>&nbsp;and installs the UpCloud provider module.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Terraform installation for UpCloud is then all set. You are now ready to start planning your first Terraform deployment. Continue on with the rest of the guide to learn how to create and deploy Terraform plans.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Planning infrastructure with Terraform<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Defining infrastructure as code brings many advantages such as simple editing, reviewing, and versioning, as well as easy sharing amongst team members.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a new build plan named for example <tt>server1.tf<\/tt> in your Terraform directory.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">touch server1.tf<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Open the file in your favourite text editor then include a provider segment for UpCloud and any number of resources as described in the example plan below.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Replace the <tt>ssh-rsa public key<\/tt>&nbsp;in the login segment with your public SSH key and path to your private SSH key in the connection settings.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">resource \"upcloud_server\" \"server1\" {\n  # System hostname\n  hostname = \"terraform.example.com\"\n\n  # Availability zone\n  zone = \"nl-ams1\"\n\n  # Number of CPUs and memory in GB\n  plan = \"1xCPU-1GB\"\n\n  template {\n    # System storage device size\n    size = 25\n\n    # Template UUID for Ubuntu 20.04\n    storage = \"01000000-0000-4000-8000-000030200200\"\n  }\n\n  # Network interfaces\n  network_interface {\n    type = \"public\"\n  }\n\n  network_interface {\n    type = \"utility\"\n  }\n\n  # Include at least one public SSH key\n  login {\n    user = \"root\"\n    keys = [ <span style=\"color: #ff0000;\">\"ssh-rsa public key\"<\/span>, ]\n    create_password = false\n  }\n\n  # Configuring connection details \n  connection {\n    # The server public IP address\n    host        = self.network_interface[0].ip_address\n    type        = \"ssh\"\n    user        = \"root\"\n    private_key = file(<span style=\"color: #ff0000;\">\"~\/.ssh\/rsa_private_key\"<\/span>)\n  }\n\n  # Remotely executing a command on the server\n  provisioner \"remote-exec\" {\n    inline = [ \"echo 'Hello world!'\" ]\n  }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once done, just save the file and you are good to go.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that Terraform needs to be able to read your private SSH key. If you get the following error:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Error: Failed to parse ssh private key: ssh: this private key is passphrase protected<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Make sure it\u2019s available and unlocked in your SSH agent or use a key that\u2019s not password protected.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you don\u2019t have an SSH key&nbsp;at hand, check out our quick guide about <a href=\"https:\/\/upcloud.com\/global\/community\/tutorials\/ \/use-ssh-keys-authentication\/\" target=\"_blank\" rel=\"noopener\">using SSH keys for authentication<\/a>&nbsp;to generate a key pair for Terraform.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Deploying your configuration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once you\u2019ve defined your infrastructure plan, next you might want to deploy it. Terraform provides easy-to-use commands for safely and predictably deploying resources and applying changes to them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, verify your build plan with the following command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">terraform plan<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This generates an execution plan that shows what actions will be taken when the plan is applied. It includes the server configuration, log in details, storage settings, and the deployment zone as seen in the example underneath.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Refreshing Terraform state in-memory prior to plan...\nThe refreshed state will be used to calculate this plan, but will not be\npersisted to local or remote state storage.\n------------------------------------------------------------------------\nAn execution plan has been generated and is shown below.\nResource actions are indicated with the following symbols:\n  <span style=\"color: #008000;\">+<\/span> create\n\nTerraform will perform the following actions:\n\n  # upcloud_server.server1 will be created\n  + resource \"upcloud_server\" \"server1\" {\n      <span style=\"color: #008000;\">+<\/span> cpu                  = (known after apply)\n      <span style=\"color: #008000;\">+<\/span> hostname             = \"terraform.example.com\"\n      <span style=\"color: #008000;\">+<\/span> id                   = (known after apply)\n      <span style=\"color: #008000;\">+<\/span> mem                  = (known after apply)\n      <span style=\"color: #008000;\">+<\/span> plan                 = \"1xCPU-1GB\"\n      <span style=\"color: #008000;\">+<\/span> title                = (known after apply)\n      <span style=\"color: #008000;\">+<\/span> zone                 = \"nl-ams1\"\n\n      <span style=\"color: #008000;\">+<\/span> login {\n          <span style=\"color: #008000;\">+<\/span> create_password   = true\n          <span style=\"color: #008000;\">+<\/span> keys              = [\n              <span style=\"color: #008000;\">+<\/span> \"ssh-rsa public key\",\n            ]\n          <span style=\"color: #008000;\">+<\/span> password_delivery = \"email\"\n          <span style=\"color: #008000;\">+<\/span> user              = \"root\"\n        }\n\n      <span style=\"color: #008000;\">+<\/span> network_interface {\n          <span style=\"color: #008000;\">+<\/span> bootable            = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> ip_address          = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> ip_address_family   = \"IPv4\"\n          <span style=\"color: #008000;\">+<\/span> ip_address_floating = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> mac_address         = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> network             = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> source_ip_filtering = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> type                = \"public\"\n        }\n      <span style=\"color: #008000;\">+<\/span> network_interface {\n          <span style=\"color: #008000;\">+<\/span> bootable            = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> ip_address          = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> ip_address_family   = \"IPv4\"\n          <span style=\"color: #008000;\">+<\/span> ip_address_floating = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> mac_address         = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> network             = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> source_ip_filtering = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> type                = \"utility\"\n\n      <span style=\"color: #008000;\">+<\/span> template {\n          <span style=\"color: #008000;\">+<\/span> address = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> id      = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> size    = 25\n          <span style=\"color: #008000;\">+<\/span> storage = \"01000000-0000-4000-8000-000030200200\"\n          <span style=\"color: #008000;\">+<\/span> tier    = (known after apply)\n          <span style=\"color: #008000;\">+<\/span> title   = (known after apply)\n        }\n    }\n\nPlan: 1 to add, 0 to change, 0 to destroy.\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The values shown are assigned at deployment and cannot be determined ahead of time. They can be queried once the server is online.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, deploy the configuration by executing the plan with the command below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">terraform apply<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Reply <tt>yes<\/tt>&nbsp;when asked to confirm the deployment. Example output is shown below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">upcloud_server.server1: Creating...\nupcloud_server.server1: Still creating... [10s elapsed]\nupcloud_server.server1: Still creating... [20s elapsed]\nupcloud_server.server1: Still creating... [30s elapsed]\nupcloud_server.server1: Provisioning with 'remote-exec'...\nupcloud_server.server1 (remote-exec): Connecting to remote host via SSH...\nupcloud_server.server1 (remote-exec):   Host: 94.237.45.99\nupcloud_server.server1 (remote-exec):   User: root\nupcloud_server.server1 (remote-exec):   Password: true\nupcloud_server.server1 (remote-exec):   Private key: true\nupcloud_server.server1 (remote-exec):   Certificate: false\nupcloud_server.server1 (remote-exec):   SSH Agent: true\nupcloud_server.server1 (remote-exec):   Checking Host Key: false\nupcloud_server.server1: Still creating... [40s elapsed]\nupcloud_server.server1 (remote-exec): Connected!\nupcloud_server.server1 (remote-exec): Hello world!\nupcloud_server.server1: Creation complete after 40s [id=00bafe39-800b-45a4-83f1-460aff563cf5]\n\nApply complete! Resources: 1 added, 0 changed, 0 destroyed.\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You\u2019ll notice that much of the output from the apply command looks the same as planning so some of the above are truncated for brevity. Terraform performs syntax verifications again in an effort to spare you from deployment errors that could take precious time to roll back.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Separating the plan and applying commands reduces mistakes and uncertainty at scale. Plans show operators what would happen upon the apply command to execute changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Managing resources<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When you need to make changes to your infrastructure, simply update the configuration file and apply the changes. As the configurations change, Terraform determines what is different and creates an incremental execution plan to perform the updates.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open your Terraform plan in an editor and find the server configuration plan. Change the plan to increase the resources allocated to your server. You can see the available preconfigured plans in your <a rel=\"noopener\" href=\"https:\/\/hub.upcloud.com\/deploy\" target=\"_blank\">UpCloud control panel<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">resource \"upcloud_server\" \"server1\" {\n  # System hostname\n  hostname = \"terraform.example.com\"\n\n  # Availability zone\n  zone = \"nl-ams1\"\n    \n  # Number of CPUs and memory in MB\n  <span style=\"color: #ff0000;\">plan = \"1xCPU-2GB\"\n<\/span>...\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Save the file with the changes, then verify your build plan again.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Refreshing Terraform state in-memory prior to plan...\nThe refreshed state will be used to calculate this plan, but will not be\npersisted to local or remote state storage.\n\nupcloud_server.server1: Refreshing state... [id=00bafe39-800b-45a4-83f1-460aff563cf5]\n------------------------------------------------------------------------\nAn execution plan has been generated and is shown below.\nResource actions are indicated with the following symbols:\n  <span style=\"color: #ff9900;\">~<\/span> update in-place\n\nTerraform will perform the following actions:\n\n  # upcloud_server.server1 will be updated in-place\n  <span style=\"color: #ff9900;\">~<\/span> resource \"upcloud_server\" \"server1\" {\n        cpu                  = 1\n        hostname             = \"terraform.example.com\"\n        id                   = \"00bafe39-800b-45a4-83f1-460aff563cf5\"\n        mem                  = 1024\n      <span style=\"color: #ff9900;\">~<\/span> plan                 = \"1xCPU-1GB\" <span style=\"color: #ff9900;\">-&gt;<\/span> \"1xCPU-2GB\"\n        title                = \"terraform.example.com (managed by terraform)\"\n        zone                 = \"nl-ams1\"\n...\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, apply the change to see the results. Reply <tt>yes<\/tt> again to confirm when requested.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">terraform apply<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">upcloud_server.server1: Refreshing state... [id=00bafe39-800b-45a4-83f1-460aff563cf5]\n\nAn execution plan has been generated and is shown below.\nResource actions are indicated with the following symbols:\n  <span style=\"color: #ff9900;\">~<\/span> update in-place\n\nTerraform will perform the following actions:\n\n  # upcloud_server.server1 will be updated in-place\n  <span style=\"color: #ff9900;\">~<\/span> resource \"upcloud_server\" \"server1\" {\n        ...\n      <span style=\"color: #ff9900;\">~<\/span> plan                 = \"1xCPU-1GB\" <span style=\"color: #ff9900;\">-&gt;<\/span> \"1xCPU-2GB\"\n        ...\n    }\n\nPlan: 0 to add, 1 to change, 0 to destroy.\n\nDo you want to perform these actions?\n  Terraform will perform the actions described above.\n  Only 'yes' will be accepted to approve.\n\n  Enter a value: yes\n\nupcloud_server.server1: Modifying... [id=00bafe39-800b-45a4-83f1-460aff563cf5]\nupcloud_server.server1: Still modifying... [id=00bafe39-800b-45a4-83f1-460aff563cf5, 10s elapsed]\nupcloud_server.server1: Still modifying... [id=00bafe39-800b-45a4-83f1-460aff563cf5, 20s elapsed]\nupcloud_server.server1: Still modifying... [id=00bafe39-800b-45a4-83f1-460aff563cf5, 30s elapsed]\nupcloud_server.server1: Modifications complete after 40s [id=00bafe39-800b-45a4-83f1-460aff563cf5]\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will see Terraform&nbsp;modify the server resources according to the differences between the server\u2019s&nbsp;current state and the new plan.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the same way, you could decrease the resources allocated to your cloud server by changing the plan back to&nbsp;<tt>1xCPU-1GB<\/tt>. However, note that this does not automatically resize the disk. As while increasing the disk is simple, decreasing storage is not quite straightforward. We recommend keeping your storage small if you wish to vertically scale the server and retain the preconfigured pricing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When you are done with the test server, it can be deleted using the command underneath.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that the destroy command will delete all resources configured in that Terraform directory. In practical use, you should remove the resource configuration and use the apply command to update your infrastructure. Terraform will then figure out the differences in the live deployment and apply the necessary changes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">terraform destroy<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">upcloud_server.server1: Refreshing state... [id=00bafe39-800b-45a4-83f1-460aff563cf5]\n\nAn execution plan has been generated and is shown below.\nResource actions are indicated with the following symbols:\n  <span style=\"color: #ff0000;\">-<\/span> destroy\n\nTerraform will perform the following actions:\n\n  # upcloud_server.server1 will be <span style=\"color: #ff0000;\">destroyed<\/span>\n  <span style=\"color: #ff0000;\">-<\/span> resource \"upcloud_server\" \"server1\" {\n      <span style=\"color: #ff0000;\">-<\/span> cpu                  = 1 -&gt; null\n      ...\n    }\n\nPlan: 0 to add, 0 to change, 1 to destroy.\n\nDo you really want to destroy all resources?\n  Terraform will destroy all your managed infrastructure, as shown above.\n  There is no undo. Only 'yes' will be accepted to confirm.\n\n  Enter a value: yes\n\nupcloud_server.server1: Destroying... [id=00bafe39-800b-45a4-83f1-460aff563cf5]\nupcloud_server.server1: Still destroying... [id=00bafe39-800b-45a4-83f1-460aff563cf5, 10s elapsed]\nupcloud_server.server1: Destruction complete after 19s\n\nDestroy complete! Resources: 1 destroyed.\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check that the action about to be taken is correct and confirm the command by entering <tt>yes<\/tt> just as with previous <tt>apply<\/tt> commands.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Great job completing this guide! You should now have some resources and the basic knowledge to start building upon. This is but an introduction to Terraform which has many advanced features. Check out the Terraform <a rel=\"noopener\" href=\"https:\/\/www.terraform.io\/docs\/index.html\" target=\"_blank\">documentation to learn more<\/a>.<\/p>\n","protected":false},"author":3,"featured_media":27319,"comment_status":"open","ping_status":"closed","template":"","community-category":[223,235],"class_list":["post-2257","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=2257"}],"version-history":[{"count":0,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2257\/revisions"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=2257"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=2257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}