<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Cloud on Mike&#39;s Blog</title>
        <link>https://mikerossiter.tech/categories/cloud/</link>
        <description>Recent content in Cloud on Mike&#39;s Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-gb</language>
        <lastBuildDate>Thu, 03 Apr 2025 13:04:14 +0100</lastBuildDate><atom:link href="https://mikerossiter.tech/categories/cloud/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Issues Setting up a Linux (Kali) VM in Azure with Terraform</title>
        <link>https://mikerossiter.tech/posts/linux-vm-azure-terraform/</link>
        <pubDate>Tue, 04 Mar 2025 13:14:50 +0000</pubDate>
        
        <guid>https://mikerossiter.tech/posts/linux-vm-azure-terraform/</guid>
        <description>&lt;img src="https://mikerossiter.tech/dragon.webp" alt="Featured image of post Issues Setting up a Linux (Kali) VM in Azure with Terraform" /&gt;&lt;h1 id=&#34;issues-setting-up-a-kali-linux-virtual-machine-in-azure-with-terraform&#34;&gt;Issues Setting up a Kali Linux Virtual Machine in Azure with Terraform
&lt;/h1&gt;&lt;p&gt;Just a quick post to show how I solved a few issues I had while trying to quickly provision a Kali Linux Virtual Machine in Azure with Terraform.&lt;/p&gt;
&lt;p&gt;A quick disclaimer, I am still quite new to Azure and I am having teething problems with work that I would have otherwise done very quickly in AWS. To begin here is some basic code to setup a Linux VM (I will leave out the extra details and allow you to decide upon SSH and password requirements for now):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;resource &amp;#34;azurerm_linux_virtual_machine&amp;#34; &amp;#34;kali_linux_vm&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  name                = &amp;#34;kali-linux-vm&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  resource_group_name = azurerm_resource_group.example.name
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  location            = azurerm_resource_group.example.location
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  size                = &amp;#34;Standard_DS2_v2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  admin_username      = &amp;#34;adminuser&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  network_interface_ids = [
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    azurerm_network_interface.example.id,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  admin_ssh_key {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    username   = &amp;#34;adminuser&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    public_key = file(&amp;#34;~/.ssh/id_rsa.pub&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  os_disk {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    caching              = &amp;#34;ReadWrite&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    storage_account_type = &amp;#34;Standard_LRS&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  source_image_reference {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    publisher = &amp;#34;kali-linux&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    offer     = &amp;#34;kali&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    sku       = &amp;#34;kali-2024-2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    version   = &amp;#34;latest&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  plan {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    name      = &amp;#34;kali-2024-2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    publisher = &amp;#34;kali-linux&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    product   = &amp;#34;kali&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Very basic and very readable. &amp;ldquo;But Mike!&amp;rdquo; I hear you say, &amp;ldquo;The &lt;em&gt;&amp;ldquo;plan&amp;rdquo;&lt;/em&gt; isn&amp;rsquo;t on the example on the Terraform website! And where did you get all that amazing information?&amp;rdquo;. Very well observed, I shall respond. BASICALLY, my VM complained profusely if there wasn&amp;rsquo;t a plan block included. So I included it. And where did I get all that lovely information from? Well I had to tiptoe into the &lt;a class=&#34;link&#34; href=&#34;https://azuremarketplace.microsoft.com/en-gb/home&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;marketplace&lt;/a&gt;. That wonderful joint. And from there decided which image I would like to deploy. This time I chose Kali Linux. Aww, cute. You see, the values in Terraform need to exactly match the infrastructure in the marketplace. The next step is to use the Azure CLI to obtain a nice table of what is available to us.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;az login
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;az vm image list --publisher kali-linux --all --output table
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From here you will see a table that includes &lt;strong&gt;Architecture, Offer, Publisher, Sku, Urn and Version&lt;/strong&gt;. These match the source_image_reference requirements easily but not the plan.&lt;/p&gt;
&lt;p&gt;For the plan you want to match &lt;strong&gt;publisher = publisher, offer = product and sku = name&lt;/strong&gt;. See above Terraform for reference.&lt;/p&gt;
&lt;h2 id=&#34;why-do-we-need-a-plan-block&#34;&gt;Why Do We Need A Plan Block?
&lt;/h2&gt;&lt;p&gt;I don&amp;rsquo;t really know! ChatGPT says that some marketplace images are private and just do so deal with it 😎. You could probably check by running more elaborate CLI commands but no one needs that in their life.&lt;/p&gt;
&lt;h2 id=&#34;further-issues&#34;&gt;Further Issues
&lt;/h2&gt;&lt;p&gt;Upon Apply I also had an issue I didn&amp;rsquo;t expect and wasn&amp;rsquo;t recreatable within the portal if I created resources manually.&lt;/p&gt;
&lt;p&gt;What happened was I got this strange error, something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;unexpected status 400 (400 Bad Request) with error: ResourcePurchaseValidationFailed: User failed validation to purchase resources. Error message: &amp;#39;You have not accepted the legal terms on this subscription: &amp;#39;***&amp;#39; for this plan. Before the subscription can be used, you need to accept the legal terms of the image.&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So I tried shouting &amp;ldquo;I ACCEPT&amp;rdquo; at my machine but nothing happened. SO instead I decided to look into how to solve this issue, starting with Terraform.&lt;/p&gt;
&lt;p&gt;On the Terraform Registry there is a very vague &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/marketplace_agreement&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;agreement resource&lt;/a&gt; that says it works sometimes but not all the time. &amp;ldquo;Awesome&amp;rdquo; I thought!&lt;/p&gt;
&lt;p&gt;And as expected it didn&amp;rsquo;t work. It also didn&amp;rsquo;t work if I put a &lt;code&gt;depends_on&lt;/code&gt; statement in my vm code. At this point I did feel like throwing the towel in but I continued. This is what worked for me. And it&amp;rsquo;s more CLI work but hey there you go.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;az vm image terms accept --publisher kali-linux --offer kali --plan kali
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;az vm image terms show --publisher kali-linux --offer kali --plan kali
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The second command should display &lt;code&gt;&amp;quot;accepted&amp;quot;, true,&lt;/code&gt; in lovely readable json at the top of the result.&lt;/p&gt;
&lt;p&gt;Therefore I needed to accept the terms manually in the CLI before it could build the resource.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t like this! And if this works for you, I bet you won&amp;rsquo;t like it either! It should be acceptable in the pipeline or apply stage of your build but anyway. This worked for me. I have much more to learn but before I forgot all about this, I wanted to share my experience.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>VPC IP Address Selector</title>
        <link>https://mikerossiter.tech/posts/vpc-ip-address-selector/</link>
        <pubDate>Thu, 18 Jan 2024 13:28:39 +0000</pubDate>
        
        <guid>https://mikerossiter.tech/posts/vpc-ip-address-selector/</guid>
        <description>&lt;img src="https://mikerossiter.tech/ips.png" alt="Featured image of post VPC IP Address Selector" /&gt;&lt;h1 id=&#34;cidr-block-tool-for-vpc-ip-addresses&#34;&gt;CIDR block tool for VPC IP addresses
&lt;/h1&gt;&lt;p&gt;This tool will take an IP address written by yourself and the number of IP addresses you require for your VPC on AWS or other since this is not something you want to get wrong as you may need to migrate your resources later if you underestimate the number of IPs you need. It will then output the IP with the correct CIDR block and the IP range you will receive. Remember in AWS the first three addresses are reserved for the VPC router, DNS and future use and the final address is used as the broadcast address. Also, the amount of IP addresses that will be returned will be a close estimation of what you have requested so double check the range after entering the values. &lt;em&gt;ALSO, if you&amp;rsquo;re testing this out for use with a VPC in AWS then remember that you only have between /16 (65,536 IP addresses) to /28 (16 IP addresses)!&lt;/em&gt;&lt;/p&gt;
&lt;body&gt;
    &lt;label for=&#34;ipAddress&#34;&gt;IP Address:&lt;/label&gt;
    &lt;input type=&#34;text&#34; id=&#34;ipAddress&#34; placeholder=&#34;Enter the IP address&#34; value=&#34;10.0.0.0&#34;&gt;
    &lt;label for=&#34;numAddresses&#34;&gt;Number of IP Addresses:&lt;/label&gt;
    &lt;input type=&#34;number&#34; id=&#34;numAddresses&#34; placeholder=&#34;Enter the number of IP addresses&#34; value=&#34;100&#34;&gt;
    &lt;button onclick=&#34;calculateCIDR()&#34;&gt;Calculate CIDR Block&lt;/button&gt;
    &lt;p id=&#34;result&#34;&gt;&lt;/p&gt;
    &lt;p id=&#34;ipRange&#34;&gt;&lt;/p&gt;
    &lt;script src=&#34;https://mikerossiter.tech/js/ip-vpc.js&#34;&gt;&lt;/script&gt;
&lt;/body&gt;
</description>
        </item>
        
    </channel>
</rss>
