TagSubscriptions

WVD Management Tool – Cross Tenant Access Fix

With the announcement of WVD (Windows Virtual Desktop) moving into GA today I thought I’d spin my lab back up again and try and get the WVD Management Web App Tool working.

My last attempt a few weekends ago was unsuccessful and I didn’t have any time to carry on troubleshooting so I deleted the Resource Group and forgot about it the long To-Do list for another day.

So this evening as the working day was nearing it’s end, I headed back into the Azure portal and attempted to deploy the WVD Management Tool.

My WVD Setup – Azure AD, Subscriptions & Resources

Issue #1 – Azure Automation Job Failing

This was a pretty simple one in the end. The Azure AD user’s password I was giving in the ARM template parameters had expired.

This user needs to be an Azure AD Global Administrator and have the RBAC permissions on the Subscription you want to deploy the WVD Management Tool too.

Issue #2 – My Subscription & Azure AD Tenant Aren’t Linked

Now most people will have a single Azure AD Tenant and all their users synced to this and also all of their Azure Subscriptions linked to the same tenant.

However I do not, for a number of reasons, mainly for giving me the opportunity to test a lot of the more complicated deployments.

See the above diagram in this post for my setup explained; hopefully!

So when the WVD Management Web App Tool deploys I have to put it in my subscriptions linked to the ‘jackjacktraceyco.onmicrosoft.com’ Azure AD Tenant.

However all of my WVD authentication is sourced from my ‘jtlab.cloud’ Azure AD Tenant as I use Azure AD Connect to sync my users & groups from the ‘LAB-DC-01’ Active Directory Domain Controller.

Once I figured out Issue #1 and the WVD Management Tool was successfully deployed I tried to login to it with my WVD Tenant Admin User (in the ‘jtlab.cloud’ tenant) and got the below error:

As you can, sort of, see it is saying that the Application with the ID of XXXXXXXX cannot be found in the directory ‘jtlab.cloud’ (you’ll have to trust me on this one).

Now this isn’t really an issue caused by an error in the ARM template provided by Microsoft, its actually done exactly as I’ve told it too. The issue is my setup!

However this setup is likely to be fairly common, especially in a partner world or a provider doing a DaaS (Desktop-as-a-Service) offering.

The Fix

Luckily this is quite an easy one.

  1. Login to the Azure Active Directory Management Portal as a user with the Global Administrator role into the Azure AD Tenant where your Subscriptions and therefore WVD Management Tool is deployed – https://aad.portal.azure.com
  2. Select the ‘Azure Active Directory’ blade > then ‘App Registrations’ > then search for the Application ID referenced in the error or search for ‘wvd’.
  3. Select the App Registration > then select ‘Authentication’ > then scroll to the bottom of the show blade on the right until you get to the ‘Supported account types’ section. Change the radio button select to the option called: ‘Accounts in any organizational directory (Any Azure AD directory – Multitenant)’
  4. Click Save

And that is all you need to do to fix the login. This now allows other Azure AD tenants to sign into the WVD Management Tool that you created. Which is exactly what I need for my setup!

Hope this helps some of you out there!

 

Like, Share, Follow!
error

Azure Resource Locks – The What & Why

Today I want to give you all an overview of Azure Resource Locks. Firstly about what they are and can do, then secondly how you can use them and some best practices around them. And finally a few things to watch out for so you don’t get caught out when using them; believe me it’s easily done!

What are Azure Resource Locks?

Resource Locking within Azure provides a method to lock subscriptions, resource groups or individual resources to protect them from accidental deletion and changes; even for administrators (depending on their RBAC role).

Resource Locks come in 2 levels; CanNotDelete (displayed as ‘Delete’ in the portal) or ReadOnly (displayed as ‘Read-only’ in the portal).

As the names suggest, CanNotDelete means the resources with the lock applied can be read and modified, but they cannot be deleted. The ReadOnly lock means that the resources with the lock applied can only be read but not modified or deleted.

Both types of lock can actually cause some resources to stop functioning as you’d expect so be aware. More on this later!

Resource locks can also only be created by users assigned the ‘Owner’ or ‘User Access Administrator’ RBAC roles. More specifically any users with roles that grant the following RBAC permissions: ‘Microsoft.Authorization/*’ or ‘Microsoft.Authorization/locks/*’. So you don’t need to worry about anyone with write permissions on Resource Groups or VMs etc… creating locks on everything and potentially breaking other services without knowing about it etc…

How should I use Azure Resource Locks?

Now you may think that once deployed putting ReadOnly locks on everything is probably the best thing to go and do. And in some select scenarios I may even agree with you, however this is not best practice; so only do this if you absolutely have too!

Resource Locks can be applied at the following Azure governance scoping levels:

  • Subscription
  • Resource Group
  • Resource

In my opinion, applying locks at the Subscription level is way to high in the governance hierarchy structure and makes using Azure clunky; as everything you deploy within that subscription will inherit the lock from the subscription level.

Taking it to the other end of the governance hierarchy at placing locks at the Resource level can again be very tedious and difficult to manage and keep on top of. However in some cases it can actually be very useful.

Think of a scenario where you have applied a CanNotDelete lock at the resource group level but on the VPN gateway you have deployed within the resource group you want to restrict anyone from changing anything about its configuration. Applying a ReadOnly lock on the VPN gateway resource as well will mean that the rest of the resource group’s resources can be modified as they need to be but the VPN gateway is completely locked and cannot be modified at all without the lock being removed first. Removing the lock itself requires specific permissions, as explained in the above section, so this become a very handy way of locking things down further.

It should also be stated that if 2 locks, 1 in CanNotDelete mode & 1 in ReadOnly mode, the most restrictive lock (ReadOnly) takes precedence.

So the only scope we haven’t mentioned yet is the Resource Group level. This is where I suggest the majority of your locks are applied. However this does rely on you having split resources in some fashion between multiple resource groups. Whether that’s by application, business unit or service; as long as they are split and not all in a single resource group this approach will work nicely!

Applying locks at the Resource Group level is also the advised best practice from Microsoft under the Enterprise Scaffold framework (no part of the Cloud Adoption Framework). And as explained in the above scenario its give you the best flexibility for control without the locks becoming a restricting factor in using Azure on a daily basis.

When governance controls become a blocker for using and consuming Azure you’ll find people will try as many ways as possible to avoid following the controls you have put in place. So my advice is to use them as guard rails and not super secure enforcement rules to stop this from happening.

How do I create and apply Azure Resource Locks?

This is actually quite easy and I find doing it via the Azure Portal is the best way as you can check what resources will be impacted very easily & quickly due to the visual nature of the portal. However locks can be applied via PowerShell, AZ CLI, ARM Templates & Terraform etc…

In the below example I will place a ReadOnly lock on my test resource group which contains a single storage account.

  1. Log into the portal and select the Resource Group you wish to apply a lock to
  2. Select the ‘Locks’ blade from the navigation bar on the right
  3. Click ‘Add’
  4. Fill out the details as required and select the ‘Lock Type’ then click ‘OK’
  5. The lock will now be applied – Note the ‘Scope’ is shown in the lock overview blade as well as ‘Notes’. Make sure you use notes as it helps the next person when they come across your locks.
  6. That is it. You can follow the same instructions and a Subscription or Resource level and the steps are the same.

If we now lock at the Storage Account in this resource group we will see it has inherited the lock.

If I now try to amend the storage account you will see that even though I’m an owner on the Subscription the lock still applies to me and I must manually remove it in order to amend the storage account or delete it.

Things to watch out for with Azure Resource Locks

As mentioned at the beginning of this blog post, using resource locks can actually break some functionality with resources.

The ones I know of to date are as follows:

  1.  Listing Storage Account Access Keys This happens whether using the Portal, PowerShell, AZ CLI etc… as they all utilise the Azure Resource Manager (ARM).
  2. Azure Backup of VM’s Managed Disks(Thanks to Adin Ernie for the screenshot of this as I didn’t have one to hand at time of writing.)
    This occurs because the ‘RestorePointCollection’ object is treated as a separate Resource object by ARM. So you cannot place any locks on Resource Groups that contain these objects. The resource group name will look like this: AzureBackupRG_ukwest_1 However the region name will change depending on where you are deploying resources and backing up etc….

Summary

Hopefully this article has given you an in depth overview of Azure Resource Locks and how they can be and should be used.

Further reading can be found on the Microsoft Docs pages as always.

Like, Share, Follow!
error

CSP Multi-Channel Model & Azure Subscriptions

A slightly less technical log post for today’s topic, however a vital one for anyone using/thinking of using an Azure CSP Subscription.

Firstly a quick explanation of the CSP (Cloud Solution Provider) program.

CSP is a program that partners can sign up to in order to sell Microsoft Cloud Services like Azure, Office 365, Microsoft 365, EM+S and other similar services to their customers directly; instead of customers having to purchase them directly from  Microsoft.

CSP has had a massive uptake over the last 3-5 years and pretty much every MSP (Managed Service Provider) has access to a CSP program, whether directly or indirectly, to sell Microsoft Cloud services to their customer.

The key fact around CSP is that the CSP partner you chose to purchase Office 365 or Azure subscriptions from etc… is responsible for billing the client and providing support for both billing and technical support. Meaning the CSP partner effectively becomes the single point of contact for the client for all things relating to the Microsoft Cloud.

Further information around CSP can be found here: https://docs.microsoft.com/en-us/azure/cloud-solution-provider/overview/azure-csp-overview

I’ll be blogging soon about things you should consider before choosing between CSP and other subscriptions types for Azure (EA/PAYG etc…). So watch out for that.

However this post focuses on a particular limitation of CSP Azure Subscriptions in a Multi-Channel Model approach that is commonly not known about and can be a road block to project flows if not known about.

What is the CSP Multi-Channel Model?

When CSP first launched it only allowed the provisioning CSP partner to add/remove/amend licenses and subcriptions for each customer. So if you had a scenario where the customer, “ACME Corporation”, purchased 10 X Office 365 E3 licenses from CSP Partner 1; Only CSP Partner 1 could sell them additional licenses or provision any other services available in the CSP program, like Azure etc…

This obviously locked customers like, “ACME Corporation”, into a relationship with CSP Partner 1 until the end of time. Both customers and other CSP partners didn’t like this as effectively people where just getting any customer to sign up for CSP for a tiny amount of services to lock them in for future consumption costs.

Microsoft then released the CSP Multi-Channel Model which allowed another partner, say CSP Partner 2 in our above scenario, to start a CSP relationship with “ACME Corporation” which would allow them to purchase CSP services from both CSP partners at the same time; even for the same license SKU types.

For example “ACME Corporation” could have 10 x Office 365 E3 licenses from CSP Partner 1 & then start another relationship with CSP Partner 2 and purchase and additional 5 x Office 365 E3 licenses from them also. In this scenario each partner bills “ACME Corporation” for 10 x Office 365 E3 licenses separately and everyone is happy.

Also an important note is that when another relationship is established with another CSP partner they cannot amend and services/licenses provided by another other CSP partner to the same customer; very handy indeed!

So why doesn’t this work in the same way for Azure subscriptions?

Unfortunately for Azure subscriptions the CSP Multi-Channel model doesn’t allow 2 CSP partners to each provide Azure subscriptions to a customer.

So in our example scenario above, “ACME Corporation” could be provided Office 365 licenses from both CSP partners at the same time but only 1 CSP partner could provide an Azure subscription at any one time.

This can be quite a road blocker when not known about! It is certainly 1 thing I have had to stop from occurring multiple times in the last year or so and it’s becoming ever more popular as more customer take services from CSP partners.

There is a note on the following Microsoft Docs page for adding existing Azure customers in CSP that is often not missed and not read and understood in full.

The note is shown below:

Is there a way around this?

There is but its not simple and takes considerable thought and consideration before starting the process.

The only way around this is to transfer the Azure services between CSP partners. This does mean the source partner will lost all billing and revenue from the Azure subscription once the transfer process is complete. However if they are providing Office 365 or any other license model based services via CSP these are not transferred during the Azure transfer process. These are in-fact very easy to switch CSP Partner 2 provisions all the same quantities and licenses for each SKU in use by the customer then CSP Partner 1 cancels all those licenses fort the customer and then each users licenses automatically flips over the the licenses provided by CSP Partner 2.

The Azure transfer process is documented fully by Microsoft here: https://docs.microsoft.com/en-us/partner-center/switch-azure-subscriptions-to-a-different-partner

The process requires involvement from both CSP partners, the customer and Microsoft support to complete the process in full. So a good relationship with all parties involved is vital to ensure a smooth transfer process!

Summary

I hope this helps customers and other CSP Partners out there as this is certainly going to become more of a day to day occurrence as more customers utilise CSP partners for Azure subscriptions.

Look out for more CSP related articles soon!

Like, Share, Follow!
error

Azure Subscription Migrations

** UPDATE – 04/09/2019 – Version 6 of the Azure Resource Migration Support Tool released – Click on link below to get a copy of it or here. **

Recently I have had an abundance of requests from our sales teams & account managers regarding Azure Subscription migrations. Whether it be from PAYG (Pay-As-You-Go) to CSP, EA to CSP, CSP to PAYG or just PAYG to PAYG.

Whatever the source and destination subscription model is, the answer I give is the same!

Every migration for each customer is going to be different 99% of the time and in the majority of cases is not as simple as the click of the migrate button from within the portal and away you go. Perhaps one day it will be; I’ll be a very happy man that day for sure!

So in this post I will share with you how I approach these requests and a tool I have developed to help speed the assessment process up significantly.

Please note this article will focus on subscription level migrations, however the tool accommodates for Resource Group level migrations as well!

Before you even think about migrating…

There are a few key points of information that you need to gather/understand when starting with one of these requests.

  1. Why does the customer want to migrate subscriptions?
  2. What subscription model are the source and destination subscriptions using; or going to use?
    1. PAYG
    2. CSP
    3. EA
    4. Other… (MSDN, BizSpark etc…)
  3. An export of all resources from all of the source subscriptions.
  4. Timescales for migration completion.

All of these questions are important to have an answer for before beginning your approach to the migration.

Questions 1 and 4 are more to help understand the “why” from the customer and to set expectations early on timescales. Because we all know sometimes timescale expectations can be unrealistic and it’s important for us to reset them accordingly if so.

Questions 2 and 3 will help define some technical paths you will need to follow and various limitations that each combination may have.

Subscription Migration Support Matrix

I feel know is a good time to lay out all of the combinations for subscription migrations and what initial approach should be taken.

Apologies for the length of this table but there are a lot of possible different combinations!

Source
Subscription
Model
Destination
Subscription
Model
Migration
Supported
Migration
Approach
Notes
PAYGEAYesJust a back-end Azure billing change.
No downtime
PAYGCSPYesResources must be migrated between subscriptions.
Possible downtime & limitations.
Check services are available in CSP.
No classic (ASM) resource supported in CSP.
PAYGMSDN/BizSparkYesResources must be migrated between subscriptions.
Possible downtime & limitations.
PAYGPAYGYesResources must be migrated between subscriptions.
Possible downtime & limitations.
EAPAYGYesResources must be migrated between subscriptions.
Possible downtime & limitations.
EACSPYesResources must be migrated between subscriptions.
Possible downtime & limitations.
Check services are available in CSP.
No classic (ASM) resource supported in CSP.
EAMSDN/BizSparkYesResources must be migrated between subscriptions.
Possible downtime & limitations.
EAEAYes/No/Not NormalIf different Azure AD Tenant same as EA to PAYG.
If same Azure AD Tenant, why are you migrating as you can just change subscription owner instead.
N.B. this not a migration I have ever come across to date.
MSDN/BizSparkEAYesJust a back-end Azure billing change.
No downtime
MSDN/BizSparkPAYGYesResources must be migrated between subscriptions.
Possible downtime & limitations.
MSDN/BizSparkCSPYesResources must be migrated between subscriptions.
Possible downtime & limitations.
MSDN/BizSparkMSDN/BizSparkYesResources must be migrated between subscriptions.
Possible downtime & limitations.
CSPMSDN/BizSparkYes/Not NormalResources must be migrated between subscriptions.
Possible downtime & limitations.
CSPEAYes/No/Not NormalBelieve this would have to be treated as if it were PAYG to PAYG as CSP subscription has some back-end billing differences. Therefore doubtful that EA subscription import/billing change process will not work.
Resources must be migrated between subscriptions.
Possible downtime & limitations.
CSPPAYGYesResources must be migrated between subscriptions.
Possible downtime & limitations.
CSPCSPYesBack end billing change but must be requested in certain way and currently no automated way to do this.
See: https://docs.microsoft.com/en-us/azure/cloud-solution-provider/customer-management/switch-subscription-to-different-csp-partner

Assessing Resource Migrations Between Subscriptions

As you have seen in the table above, the majority of migrations require you to migrate the actual Azure resources between subscriptions. As mentioned before and in the table rows, this sometime incurs downtime and also there are various limitations per Azure resource type (VM’s, NSG’s, App Services etc…).

Now there used to be a handy little tool that someone created for CSP migration assessments called the “Azure CSP Assessment”. This was an Azure hosted web app located here: https://azurecspassessment.azurewebsites.net/ but as you can see the site is now longer up and running 🙁

However using the tool was always a risk as the list of resources that support subscription migration and the various limitations changes at quite a pace; as does everything in the Azure world, right!

So it used to mean that I get an export of the customers source Azure subscription resources and resource types using the below PowerShell command:

Get-AzResource | Export-Csv PATHTOFILE.csv

Then using the exported CSV file I would use Excel and the following below pages on Azure Docs to go through each resource type and check its compatibility and limitations:

  1. https://docs.microsoft.com/en-gb/azure/azure-resource-manager/move-support-resources
  2. https://docs.microsoft.com/en-gb/azure/azure-resource-manager/resource-group-move-resources
  3. https://docs.microsoft.com/en-us/azure/cloud-solution-provider/overview/azure-csp-available-services – Only when migrating to CSP

To say this was long winded and painful is an understatement certainly!

Azure Resource Migration Support Tool

So that’s why I have created a handy Excel Workbook that does all the work in comparing against the information in links 1 and 2 above with a simple copy and paste of specific columns from the exported CSV.

I also thought it would be a shame not to share this tool so here it is available for any of you reading this to use for free!

Azure Resource Migration Support Tool V2

Azure Resource Migration Support Tool V4

Azure Resource Migration Support Tool V5

Azure Resource Migration Support Tool V6

All instructions on how to use the tool are on the “Intro Page” sheet within the workbook/spreadsheet.

I will be periodically checking the Azure Docs pages and updating any changes to resources that are now supported for migration to this tool and i will update this page with the latest version of the tool.

What do I do once I’ve used the tool to assess my resources…

Well firstly, please comment below or get in touch with me via Twitter, LinkedIn or e-mail me with any feedback or features you would like in newer releases of the tool.

Once you’ve done that and used the tool to assess your resources in your source subscription, it is highly likely you have a good idea about how you need to proceed.

I strongly suggest running this as a project within your company as it is not as simple as clicking a migrate button. I’ve even called it a “Virtual Data Centre Move” as it really can have the same potential devastating unplanned outages if you don’t treat it with the correct attention and detailed planning.

Personally I suggest building a project plan, if you have a Project Manager to help you, even better. Detail every task you are going to need to do before, during and after the migration, some examples below:

  • Create destination subscription
  • Attach destination subscription to existing (same as source subscription) Azure AD tenant – THIS IS MANDATORY AT THIS TIME, BOTH SUBSCRIPTIONS MUST BE IN THE SAME AZURE AD TENANT
  • Change Public IP SKUs for Resources: X, Y & Z
  • etc…

Once you have your plan built, start raising RFC/Changes (if required) to get this work completed. Some of this work may even require re-provisioning resources to get them on the correct SKUs etc… so it would also be prudent to get any other internal teams involved to assist with testing etc… if you aren’t able to do this yourself during your changes.

Nobody likes the dreaded out of hours phone call when something you couldn’t test doesn’t work after a change.

Once you’ve made all of the prerequisite changes, its now time to probably download the latest version of the tool, export all your resource into a CSV again and check for any additional changes that you may need to make as things may of changed from the Azure side.

If nothing has then that’s great news as you haven’t got to go back through the whole process again. You should now make sure that all Resource Providers in use in the source subscription are registered in the destination subscription.

To check the Resource Providers in use in the either subscription use the following PowerShell command (please note you’ll need to change subscriptions within your PowerShell session using the first 2 commands in the below block):

##Find Subscription ID##
Get-AzSubscription

##Change Subscription Within PowerShell Session##
Select-AzSubscription -SubscriptionId 'PASTE ID HERE'

##Check Resource Providers For Selected Subscription##
Get-AzResourceProvider -ListAvailable | Select-Object ProviderNamespace, RegistrationState

You should get the below output for the Resource Provider command. (I’m using CloudShell, check it out if you aren’t already):

Compare both subscription outputs against each other, using Export-Csv may be your friend here. And then register any providers in the destination subscription that are registered in the source subscription but not in the destination.

To register Resource Providers use the below command (again please note you’ll need to make sure you’ve changed your sessions selection to the correct subscription again using the above commands):

##Register Resource Provider##
Register-AzResourceProvider -ProviderNamespace 'PROVIDER NAMESPACE PLEASE CHANGE'

You should get the below output when registering a provider:

Once you have registered all the required providers run one last comparison check and then you can proceed to actually pushing that ‘Move to another subscription’ button on your resources/resource groups as per your plan.

Summary

As you can see by the length of this article the process is not always straight forward and can be quite a long process from start to finish.

Please let me know your feedback for the tool via any method that I mentioned above.

And more importantly I hope this article helps you plan your migration to be successful.

Like, Share, Follow!
error

Azure & The Importance Of Azure AD

Recently the amount of conversations I have had with customers and colleagues regarding Azure AD and how it links to subscriptions etc… has been astounding.

The most common misconception I see/hear is that because it has the “AD” in its title that it is believed to be a completely separate product unrelated to the fundamental required components to get started in Azure successfully.

Also I get the question from a lot of customers who are already using Azure of “Why do we have to use separate accounts to login to Azure? 

As soon as I hear the above, I instantly smile inside, because I know they haven’t understood Azure AD and its importance at the setup stage of any Azure, Office 365, Dynamics subscription creation.

So what is the importance of Azure AD, I hear you ask?

I’ll start off by showing the below diagram as this may help initiate that lightbulb moment for some of you.

The above diagram shows a typical setup that I have configured many times in the past. At the top we have an existing on-premise Active Directory Forest & Domain (acmecoporation.local) with all existing user, groups & computer objects in an OU structure.

In the middle we have the Azure AD Tenant with the *.onmicrosoft.com domain name of acmecorporation.onmicrosoft.com. 

Some important things of note about the Azure AD tenant:

  • The *.onmicrosoft.com domain name must be globally unique
    • This means checking the availability of the desired domain name is vital before beginning the creation, here is a link to a great tool to do just that
      (Believe me when I say I have seen a surprising amount of *.onmicrosoft.com domain names already been taken for some of my customers)
    • In some circumstances Microsoft themselves can help in tracking down a desired *.onmicrosoft.com domain name and asking the existing tenant owners if they are willing to give it to you
      • However, in most cases the existing tenant owners will not want to give this up as it will involve a large migration from one tenant to another
  • The *.onmicrosoft.com domain name cannot be changed once created
  • The Azure AD tenant should be treated as a single forest & domain configuration when translating to an on-premises AD deployment.
  • Azure AD doesn’t have any trusts between Azure AD tenants like you can do with an on-premises AD deployment
    • There is a feature called Azure AD B2B which is very similar. (A blog post for the future in its own right, watch this space)

The notes above are not a definitive list however they are the most common things I come across on a daily basis.

Users, Groups & Computers can be synchronised from on-premises Active Directory domains via the use of Azure AD Connect (formerly known as DirSync).

Azure AD Connect is an awesome tool that not only synchronises objects from on-premises to your Azure AD tenant, but it also can configure authentication methods (Password Hash Sync, Pass-Through Authentication, ADFS to name a few), all from a GUI based application.

It can also synchronise objects from several other on-premises AD topologies, however Microsofts has an article for this which is very well constructed so I will link to that here.

And finally at the bottom of the diagram are the various subscriptions that are linked to the Azure AD tenant.

Subscriptions can only be linked to one Azure AD tenant, so those subscriptions will only be able to use the users, groups & computer objects that are in the Azure AD tenant.

So I appreciate there is a lot to take in there but this just reiterates my point that it is some important to get it right at the beginning of your cloud journey.

So how do I make the right choice when setting up an Azure Subscription?

Again this is not as easy of a task that a lot of people believe it is. So again to help ensure you get this right I have created a workflow that will help guide you to the correct choice.

Summary

Again I apologise for the information overload in this article however, by taking the time to read through this article (probably several times) it should help you make the right decision around what to do.

Also it should help you avoid the nasty situation of having to migrate to a new subscription which is linked to the correct Azure AD tenant. Believe me these migrations are never fun!

As always comment, like & share!

Like, Share, Follow!
error

© 2019 Jack Tracey

Theme by Anders NorénUp ↑