Its Day 47 of my 100 Days of Cloud Journey, and today I sat Exam AZ-800: Administering Windows Server Hybrid Core Infrastructure (beta).
AZ-800 is one of 2 exams required for the new Windows Server Hybrid Administrator Associate certification, which was announced at Windows Server Summit 2021. The second exam is Az-801 (Configuring Windows Server Hybrid Advanced Services), which I’m taking next week so will write up a post on that then!
This certification is seen by many as the natural successor to the retired MCSE certifications which retired in January 2021, primarily because it focuses in some part on the on-premise elements within Windows Server 2019.
Because of the NDA, I’m not going to disclose any details on the exam, however I will say that it is exactly as its described – a Hybrid certification bringing together elements of both on-premise and Azure based infrastructure.
The list of skills measured as their weightings are as follows:
Deploy and manage Active Directory Domain Services (AD DS) in on-premises and cloud environments (30-35%)
Manage Windows Servers and workloads in a hybrid environment (10-15%)
Manage virtual machines and containers (15-20%)
Implement and manage an on-premises and hybrid networking infrastructure (15-20%)
Manage storage and file services (15-20%)
Like all beta exams, the results won’t be released until a few weeks after the exam officially goes live so I’m playing the waiting game! In the meantime, you can check out these resources if you want to study and take the exam:
Its Day 46 of my 100 Days of Cloud Journey, and today I’m looking at Azure Well Architected Framework.
Over the course of my 100 Days journey so far, we’ve talked about and deployed multiple different types of Azure resources such as Virtual Machines, Network Security groups, VPNs, Firewalls etc.
We’ve seen how easy this is to do on a Dev-based PAYG subscription like I’m using, however for companies who wish to migrate to Azure, Microsoft provides a ‘Well Architected Framework’ which offers guidance in ensuring that any resource or solution that is deployed or architected in Azure conforms to best practices around planning, design, implementation and on-going maintenance and improvement of the solution.
The Well Architected Framework is based on 5 key pillars:
Reliability – this is the ability of a system to recover from failures and continue to function, which in itself is built around 2 key values:
Resiliency, which returns the application to a fully functional state after a failure.
Availability, which defines whether users can access the workload if they need to.
Security – protects applications and data from threats. The first thing people would think of here is “firewalls”, which would protects against threats and DDoS attacks but its not that simple. We need to build security into the application from the ground up. To do this, we can use the following areas:
Identity Management, such as RBAC roles and System Managed Identities.
Application Security, such as storing application secrets in Azure Key Vault.
Data sovereignty and encryption, which ensures the resource or workload and its underlying data is stored in the correct region and is encrypted using industry standards.
Security Resources, using tools such as Microsoft Dender for Cloud or Azure Firewall.
Cost Optimization – managing costs to maximize the value delivered. This can be achieved in the form of using tools such as:
Azure Cost Management to create budgets and cost alerts
Azure Migrate to assess the system load generated by your on-premise workloads to ensure thay are correctly sized in the cloud.
Operational Excellence – processes that keep a system running in production. In most cases, automated deployments leave little room for human error, and can not only be deployed quickly but can also be rolled back in the event of errors or failures.
Performance Efficiency – this is the ability of a system to adapt to changes in load. For this, we can think of tools and methodologioes such as auto-scaling, caching, data partitioning, network and storage optimization, and CDN resources in order to make sure your workloads run efficiently.
On top of all this, the Well Architected Framework has six supporting elements wrapped around it:
Image Credit: Microsoft
Azure Well-Architected Review
Azure Advisor
Documentation
Partners, Support, and Services Offers
Reference Architectures
Design Principles
Azure Advisor in particular helps you follow best practises by analyzing your deployments and configuration and provides recommends solutions that can help you improve the reliability, security, cost effectiveness, performance, and operational excellence of your Azure resources. You can learn more about Azure Advisor here.
I recommend anyone who is either in the process of migration or planning to start on their Cloud Migration journey to review the Azure Well Architected Framework material to understand options and best practices when designing and developing an Azure solution. You can find the landing page for Well Architected Framework here, and the Assessments page to help on your journey is here!
Its Day 45 of my 100 Days of Cloud Journey, and today I’m looking at Azure Spot Instances and Reserved Instances.
During previous posts where I deployed virtual machines, the deployments were based on a Pay-As-You-Go pricing model, this is one of the 3 pricing models available to us in Azure. While this type of pricing is good for the likes of what I’m doing here (ie quickly spinning up VMs for a demo and then deleting them immediately), its not considered cost effective for organisations who have a Cloud Migration strategy, a long term plan to host a large number of VMs in Azure, and also need the flexibility to use low costs VMs for development or batch processing.
Lets take a look at the other 2 pricing models, starting with Azure Spot Instances.
Azure Spot Instances
Azure Spot instances allow you to utilize any unused Azure Capacity in your region at the fraction of the cost. However, at any point in time when Azure needs the capacity back, the Spot Instances will be evicted and removed from service at 30 seconds notice.
Because of this there is no SLA on Azure Spot instances, so they are not suitable for running production workloads. They are best suited for workloads that can handle interruptions, such as batch processing jobs, Dev/Test environments or Large compute workloads.
There is no availability guarantees, and availablity can vary based on size required, available capacity in your region, time of day etc. Azure will allocate the VM if there is available capacity, however there is no High Availability guarantees.
When the VMs are evicted, they can be either deallocated or deleted based on the policy you set when creating the VMs. Deallocate (this is the default) stops the VM and makes it available to redeploy (however this is not guaranteed and is based on capacity). You will also be charged for the underlying Storage Disk costs. Delete on the other hand will shut down and destroy the VMs and underlying storage.
You can see the full savings you can achieve by using Spot Instance VMs in the Azure Spot VMs Pricing Table here.
Azure Reserved Instances
Azure Reserved Instances is a way to reserve your compute capacity for a period of 1, 3 or 5 years at savings of over 70% when compared to Pay-As-You-Go pricing. This is best suited to Production workloads that need to have 24/7 runtime and high availability.
As we can see in the image from the Reservations blade in the Azure Portal above, you can purchase Azure Reserved Instances for a large number of Azure Resources, not just VMs.
Reservations can be aplied to a specific scope – that can be Subscription (single or multiple subscriptions), Resource Group or a single resource such as a VM, SQL Database or an App Service.
Once you click into any of the options on the Reservations blade, it will bring you into a list of available SKUs that you can purchase:
Another option to factor in is that Azure Reserved Instances can be use with Azure Hybrid Benefit, meaning you can use your on-premise Software Assurance-enabled Windows OS and SQL Server licences, which can bring your savings up to 80%! You can find out more about Azure Hybrid Benefit here, and get the full lowdown on Azure Reserved Instances here.
Conclusion
And thats a wrap on Azure Pricing models – you can see the cost savings you can make based on what your workloads are. Hope you enjoyed this post, until next time!
Its Day 44 of my 100 Days of Cloud Journey, and today I’m looking at Azure Arc.
Azure Arc is a service that provides you with a single management plane for services that run in Azure, On Premises, or in other Cloud Providers such as AWS or GCP.
The majority of companies have resources both in on-premise and in come cases multiple cloud environments. While monitoring solutions can provide an overview of uptime and performance over a period of time, control and governance of complex hybrid and multi-cloud environments is an issue. Because these environments span multiple cloud and data centers, each of these environments operate their own set of management tools that you need to learn and operate.
Azure Arc solves this problem by allowing you to manage the following resources that are hosted outside of Azure:
Servers – both physical and virtual machines running Windows or Linux in both on-premise and 3rd party Cloud providers such as AWS or GCP.
Kubernetes clusters – supporting multiple Kubernetes distributions across multiple providers.
Azure data services – Azure SQL Managed Instance and PostgreSQL Hyperscale services.
For this post, I’m going to focus on Azure Arc for Servers, however there are a number of articles relating to the 4 different Azure Arc supported resource types listed above – you can find all of the articles here.
Azure Arc currently supports the following Windows and Linux Operating Systems:
Windows Server 2012 R2 and later (including Windows Server Core)
Ubuntu 16.04 and 18.04 (x64)
CentOS Linux 7 (x64)
SUSE Linux Enterprise Server (SLES) 15 (x64)
Red Hat Enterprise Linux (RHEL) 7 (x64)
Amazon Linux 2 (x64)
In order to register a Physical Server or VM with Azure Arc, you need to install the Azure Connected Machine agent on each of the operating systems targeted for Azure Resource Manager-based management. This is an msi installer which is available from the Microsoft Download Center.
You can also generate a script directly from the Azure Portal which can be used on target computers to download the Azure Connected Machine Agent, install it and connect the server/VM into the Azure Region and Resource Group that you specify:
Image Credit: Microsoft
Image Credit: Microsoft
The server then gets registered in Azure Arc as a connected machine:
Image Credit: Microsoft
OK, so now we’ve got all of our servers connected into Azure Arc, what can we do with them? Is it just about visibility?
No. When your machine is connected to Azure Arc, you then have the following capabilities:
Protect Servers using Microsoft Defender for Endpoint, which is part of Microsoft Defender for Cloud
Collect security-related events in Microsoft Sentinel
Automate tasks using PowerShell and Python
Use Change Tracking and Inventory to assess configuration changes in installed software and operating system changes such as registry or services
Manage operating system updates
Monitor system performance using Azure Monitor and and collect data which can be stored in a Log Analytics Workspace.
Assign policy baselines using Azure Policy to report on compliance of these connected servers.
Conclusion
We can see how useful Azure Arc can be in gaining oversight on all of your resources that are spread across multiple Cloud providers and On Premise environments. You can check out the links provided above for a full list of capabilities, or else this excellent post by Thomas Maurer is a great starting point in your Azure Arc leaning journey.
Its Day 43 of my 100 Days of Cloud Journey, and today I’m looking at Just-In-Time (JIT) VM access and how it can provide further security for your VMs.
JIT is part of Microsoft Defender for Cloud – during the Autumn Ignite 2021, it was announced that Azure Security Center and Azure Defender would be rebranded as Microsoft Defender for Cloud.
There are 3 important points you need to know before configuring JIT:
JIT does not support VMs protected by Azure Firewalls which are controlled by Azure Firewall Manager (at time of writing). You must use Rules and cannot use Firewall policies.
JIT only supports VMs that have deployed using Azure Resource Manager – Classic deployments are not supported.
You need to have Defender for Servers enabled in your subscription.
JIT enables you to lock down inbound traffic to your Azure VMs, which reduces exposure to attacks while also providing easy access if you need to connect to a VM.
Defender for Cloud uses the following flow to decide how to categorize VMs:
Image Credit: Microsoft
Once Defender for Cloud finds a VM that can benefit from JIT, its add the VM to the “Unhealthy resources” tab under Recommendations:
Image Credit: Microsoft
You can use the steps below to enable JIT:
From the list of VMs displaying on the Unhealthy resources tab, select any that you want to enable for JIT, and then select Remediate.
On the JIT VM access configuration blade, for each of the ports listed:
Select and configure the port using one of the following ports:
22
3389
5985
5986
Configure the protocol Port, which is the protocol number.
Configure the Protocol:
Any
TCP
UDP
Configure the Allowed source IPs by choosing between:
Per request
Classless Interdomain Routing (CIDR) block
Choose the Max request time. The default duration is 3 hours.
If you made changes, select OK.
When you’ve finished configuring all ports, select Save.
When a user requests access to a VM, Defender for Cloud checks if the user has the correct Azure RBAC permissions for the VM. If approved, Defender for Cloud configures the Azure Firewall and Network Security Groups with the specified ports in order to give the user access for the time period requested, and from the source IP that the user makes the request from.
You can request this access through either Defender for Cloud, the Virtual Machine blade in the Azure Portal, or by using PowerShell or REST API. You can also audit JIT VM access in Defender for Cloud.
For a full understanding of JIT and its benefits, you can check out this article, and also this article shows how to manage JIT VM access. To test out JIT yourself, this link brings you to the official Microsoft Learn exercise to create a VM and enable JIT.
Its Day 42 of my 100 Days of Cloud Journey, and today I’m taking a look at Azure Bastion.
Azure Bastion is a PaaS VM that you provision inside your virtual network, providing secure and seamless RDP or SSH connectivity to your IAAS VMs directly from the Azure portal over TLS. When you connect via Azure Bastion, your virtual machines do not need a public IP address, agent, or special client software.
We saw in previous posts that when we create a VM in Azure, it automatically creates a Public IP Address, access to which we then need to control using Network Security Groups. Azure Bastion does away with the need for controlling access – all you need to do is create rules to allow RDP/SSH access from the subnet where Bastion is deployed to the subnet where your IAAS VMs are deployed.
Deployment
Image Credit – Microsoft
We can see in the diagram a typical Azure Bastion deployment. In this diagram:
The bastion host is deployed in the VNet.
Note – The protected VMs and the bastion host are connected to the same VNet, although in different subnets.
A user connects to the Azure portal using any HTML5 browser over TLS.
The user selects the VM to connect to.
The RDP/SSH session opens in the browser.
To deploy an Azure Bastion host by using the Azure portal, start by creating a subnet in the appropriate VNet. This subnet must:
Be named AzureBastionSubnet
Have a prefix of at least /27
Be in the VNet you intend to protect with Azure Bastion
Cross-VNET Connectivity
Bastion can also take advantage of VNET Peering rules in order to connect to VMs in Multiple VNETs that are peered with the VNET where the Bastion host is located. This negates the need for having multiple Bastion hosts deployed in all of your VNETs. This works best in a “Hub and Spoke” configuration, where the Bastion is the Hub and the peered VNETs are the spokes. The diagram below shows how this would work:
Image Credit – Microsoft
To connect to a VM through Azure Bastion, you’ll require:
Reader role on the VM.
Reader role on the network information center (NIC) with the private IP of the VM.
Reader role on the Azure Bastion resource.
The VM to support an inbound connection over TCP port 3389 (RDP).
Reader role on the virtual network (for peered virtual networks).
Security
One of the key benefits of Azure Bastion is that its a PAAS Service – this means it is managed and hardened by the Azure Platform and protects againsts zero-day exploits. Because your IAAS VMs are not exposed to the Internet via a Public IP Address, your VMs are protected against port scanning by rogue and malicious users located outside your virtual network.
Conclusion
We can see how useful Bastion can be in protecting our IAAS Resources. You can run through a deployment of Azure Bastion using the “How-to” guides on Microsoft Docs, which you will find here.
Its Day 41 of my 100 Days of Cloud Journey, and today I’m taking Day 4 and the final session of the Cloudskills.io Linux Cloud Engineer Bootcamp
This was run live over 4 Fridays by Mike Pfieffer and the folks over at Cloudskills.io, and is focused on the following topics:
Scripting
Administration
Networking
Web Hosting
Containers
If you recall, on Day 26 I did Day 1 of the bootcamp, , Day 2 on Day 33 after coming back from my AWS studies, and Day 3 was on Day 40.
The bootcamp livestream started on November 12th and ran for 4 Fridays (with a break for Thanksgiving) before concluding on December 10th. However, you can sign up for this at any time to watch the lectures to your own pace (which I’m doing here) and get access to the Lab Exercises on demand at this link:
Week 4 was all about Containers, and Mike gave us a run through of Docker and the commands we would use to download, run and build our own Docker Images. We then looked at how this works on Azure and how we would spin up Docker Containers in Azure. The Lab exercises include exercises for doing this, and also for running containers in AWS.
The Bootcamp as a whole then concluded with Michael Dickner running though the details around Permissions in the Linux File system and how they affect and can be changed for file/folder owners, users, groups and “everyone”.
Conclusion
That’s all for this post – hope you enjoyed the Bootcamp if you did sign up – if not you can sign up at the link above! I thought it was fun – the big takeaway and most useful day for me was defintely Day 3 when looking at LAMP and MEAN stack and how to run a Web Server on Linux using OpenSource technologies.
Until next time, when we’re moving on to a new topic!
Its Day 40 of my 100 Days of Cloud Journey, and today I’m back taking Day 3 of the Cloudskills.io Linux Cloud Engineer Bootcamp
This is being run over 4 Fridays by Mike Pfieffer and the folks over at Cloudskills.io, and is focused on the following topics:
Scripting
Administration
Networking
Web Hosting
Containers
If you recall, on Day 26 I did Day 1 of the bootcamp, and completed Day 2 on Day 33 after coming back from my AWS studies. Having completed my Terraform learning journey for now, I’m back to look at Day 3.
The bootcamp livestream started on November 12th, continued on Friday November 19th and December 3rd, and completed on December 10th. So I’m a wee bit behind! However, you can sign up for this at any time to watch the lectures to your own pace (which I’m doing here) and get access to the Lab Exercises on demand at this link:
Week 3 consisted of Mike going through the steps to create a website hosted on Azure using the LAMP Stack:
A stack of Lamps
No, not that type of lamp stack. I had heard the LAMP Stack before but never really paid much attention to it because in reality, it sounded too much like programming and web development to me. The LAMP Stack refers to the following:
L – Linux Operating System
A – Apache Web Server
M -MySQL Database
P – PHP
The LAMP Stack is used in some of the most popular websites in used on the internet today, as its an OpenSource and low cost alternative to commercial software packages.
At the time of writing this post, the world is in the grip of responding to the Log4j vulnerability, so the word “Apache” might scream out to you as something that we shouldn’t be doing. Follow the advice from your software or hardware vendor, and patch as much as you can and as quickly as you can. There is an excellent GitHub Repository here with full details and updates from all major vendors, its a good one to bookmark to check and see if you or your Customers infrastructure may be affected.
The alternative to the LAMP Stack is the MEAN Stack (I could go for another funny meme here but that would be too predicatable!). MEAN stands for:
M – MongoDB (data storage)
E – Express.js (server-side application framework)
A – AngularJS (client-side application framework)
N – Node.js (server-side language environment although Express implies Node.js)
Different components, but still open source so essentially trying to achieve the same thing. There is a Microsoft Learn path covering Linux on Azure, which contains a full module on building and running a Web Application with the MEAN Stack on an Azure Linux VM – this is well worth a look.
Conclusion
That’s all for this post – I’ll update as I go through the remaining weeks of the Bootcamp, but to learn more and go through the full content of lectures and labs, sign up at the link above.
I’ll leave you with a quote I heard during the bootcamp that came from the AWS re:Invent 2021 conference – every day there are 60 million EC2 instances spun up around the world. Thats 60 million VMs! And if we look at the Global Market Share across the Cloud providers, AWS has approx 32%. Azure has 21%, GCP has 8%, leaving the rest with 39%. So its safe to say over 100 million VMs daily across the world. It means VMs are still pretty important despite the push to go serverless.
Its Day 38 of 100 Days of Cloud, and I’m continuing my learning journey on Infrastructure as Code (IaC) by using Terraform.
In the previous post, we looked at the different types of variables we can use in Terraform, how we reference them across across terraform config files, and how powerful they can be in helping to make our code reusable.
Todays post is all about modules, which are used to break our terraform deployments up into multiple segments that are much easier to manage. Lets dive in and take a look.
Modules
Modules are a way to split your Terraform code into multiple segments that they can be managed more easily and by cross functional teams.
Lets go back to our traditional setup, which will have the following components:
Operating System
Network Connectivity
Database
Web Application
In our first post on Terraform back on Day 35, we had all of these bundled into a single main.tf file. As our infrastructure footprint in Azure or other Cloud Services grows, this single file will grow exponentially and will make management very dificult, particularly if multiple teams are accessing. There is also the risk that mistakes can be made that could take down the entire infrastructure.
Modules effectively sit in their own file structure, and are called from the main.tf file. If we look at the example below, the root or parent main.tf file sits at the top of the directory structure, and we then have the directory for the storage-account module sitting below that with its own main.tf and variables.tf configuration files :
If we look at the main.tf file, we can see that the resource group code is there as normal, however when we get down to create the storage account, we’re calling the module from the underlying directory structure. If we look the main.tf file within the module, we can see that it contains the basic information required to create the storage account:
What’s missing here is the Terraform source/version and provider code blocks, however in a modules configuration all of that happens in the parent main.tf file. So when we run terraform apply on the parent directory, all providers for the child modules are initialised also.
So why bother break it all up into modules? It goes back to what we said at the start about managing our code effectively, and breaking each of the components out to be managed individually. This also helps from a source repository perspective: instead of having all elements in a single file managed by multiple users or departments, each module can have its own source repository (in Github for example) managed by a teamthat can then be pulled from the repository whenever changes are made. This whats known as “Mono Repo” versus “Multi Repo”.
Image Credit: Luke Orrelana/Cloudskills.io
In the module block, we can also directly reference a Github repository to get the most up to date version of our code. There are multiple sources that can be referenced directly in the code, and full details can be found here.
Learning Resources
Lets wrap this up by looking the learning resources that are available. There are loads of excellent Terraform leaning resources out there. The best place to start is at HashiCorp Learn, which has full tutorials for all of the major cloud providers. Terraform Registry is the place to go for all providers and modules you need to deploy infrastructure.
You then need to look at courses – the aforementioned Luke Orrelana does an excellent Terraform on Azure course over at Cloudskills.io, and Michael Levan has a Terraform for All course on his YouTube Channel. Both Luke and Michael are HashiCorp Ambassadors which is teh HashiCorp equivalent of an MVP, so if you see these guys producing content you know its going to be good (and definitely doing a better job than me of trying to explain how this works!).
Conclusion
And thats all for today! I hope you’ve enjoyed the last few posts on Terraform and learning how powerful a tool it can be. Until next time!
Its Day 37 of 100 Days of Cloud, and I’m continuing my learning journey on Infrastructure as Code (IaC) by using Terraform.
In the previous post, we looked at how Terraform State stores information and acts as a database of the resources deployed in Azure. We also looked at Interpolation and how this is used to reference different parts of the Terraform configuration and the dependencies needed to deploy parts of our infrastructure (such as deploying a subnet into a vnet).
Todays post is all about variables – we saw a sample of that on our first post where I used some variables when initially deploying our Resource Group. However, we need to go deeper than that and see how powerful variables can be in helping to make our code reusable, because ultimately that is the point of using Infrastructure as Code. So lets dive in and take a look.
Types of Variables
Lets go back to Day 35 when I introduced variables in my resource group deployment. We saw the following 2 variables defined in the variables.tf file:
String Variable
This is the first of our variable types which is a string. This is a sequence of characters representing text, so in our example above it represents the prefix to be used for the resource group name, and also the default location to deploy our resource group into. You could also use this for the likes of admin usernames/passwords, or VM Size/Type we wish to deploy.
List Variable
The next type of variable is a list, which is a sequence of values. In our example, this can be used to define the address space for vnets or subnets. Lists are always surrounded by square brackets.
Map Variable
Next type is a map – this is a list of key value pairs where each value is defined by a label – so in the example above, we are using the map variable to define the type of storage we want to use based on the locations.
Object Variable
Next type is object – this is a structured variable that can contain different types of values where named attributes each have their own type.
There are 2 other types of variables – a number (which can be a whole number or a fraction) or a boolean variable (which is basically true or false).
So thats the list of variable types, and the above examples show how they would be defined in our variables.tf file. But for the most part the above is just a list of definitions of variables, so where do we store the actual values we want to use?
Variable Inputs
There are 3 ways we can input variables for use with our Terraform code:
Environment Variables – this uses the “TF_VAR_” prefix for all variables you want to store locally. So for example, to store a password variable, you would run export TF_VAR_PASSWORD="password", and then declare the variable in the variables.tf file.
Command Line Switch- we can just use the -var parameter on the command line to input the variables when running terraform apply. So for example, we could run terraform apply -var="location=northeurope" to specify the location we want to deploy to.
terraform.tfvars file – this is a file that is deployed in the same location as the main.tf and variables.tf files and contains a set of key value pairs that are the variable and its value. An exmaple of this is shown below:
We can see that the variables are on the left and the values are on the right.
Calling Variables in Main.tf
So now we have our variables defined in our terraform.tfvars file, we can now call them from our main.tf when running terraform apply. If you recall on Day 35, I used the var. syntax in the code to call the variables from variables.tf. If we look at the main.tf file now, we can see where this is now calling all of our variables, for example virtual network and subnet:
And below is the virual machine code block:
Now, the eagle-eyed will have noticed that although I’m calling a var.admin_password variable, I didn’t have that defined in my terraform.tfvars file. What will happen here when I run terraform apply is that I will be prompted to input the password, or indeed any variables that are missing.
There is another safer, more secure and in my opinion much cooler way to call the password in, and thats by calling in a secret that is stored in Azure Key Vault. You can find the code for this here.
Conclusion
So now we’re starting to piece things together and understand how the code can become re-usable. For example, we could just copy the main.tf and variables.tf files out and create separate terraform.tfvars files for multiple deployments across multiple teams or regions depending on requirements.
And thats all for today! In the final post in the Terraform series, we’ll dive into modules and how they can used for multiple resources in your architecture when using Terraform. Until next time!