A Step-by-Step Guide to Moving Your IIS .NET Applications from On-Premises to Azure Environment

 Transitioning Seamlessly: A Step-by-Step Guide to Moving Your IIS .NET Applications from On-Premises to Azure Environment

Introduction:

In today’s digitally-driven world, businesses are seeking efficient, scalable, and cost-effective solutions for their applications. The move from on-premises hosting to a cloud-based environment, such as Azure, has become a strategic imperative. This article offers a step-by-step guide to successfully transitioning your IIS .NET applications from on-premises to the Azure environment. By integrating Azure DevOps, Jenkins, and GitHub, you can leverage the power of continuous integration and deployment, making the transition smooth and efficient.

 

Why Move to Azure?

Cloud computing continues to redefine the landscape of modern business. Microsoft Azure, with its robust infrastructure, has emerged as a leader in this space, providing extensive capabilities for deploying, managing, and scaling applications.

 

 Key Benefits of Azure:

 

Scalability and Flexibility: Azure allows you to scale up or down based on your application’s demand, leading to cost savings.

Reliability and Security: Microsoft invests heavily in security, making Azure one of the most secure cloud platforms.

Integration with Tools: Azure seamlessly integrates with various DevOps tools like Jenkins, Azure DevOps, and GitHub, simplifying the deployment process.

Planning the Migration: Step-by-Step

The successful transition of your IIS .NET applications to the Azure environment relies on a strategic and systematic approach. The following steps provide a roadmap for this journey.

 

 Step 1: Pre-Migration Assessment

Before initiating the migration process, conduct an assessment of your current .NET applications. This helps identify potential issues that could arise during the migration.

 

Subtasks in Pre-Migration Assessment

 

Review the application’s architecture

Analyze the application’s dependencies

Evaluate the security requirements

Step 2: Set Up Azure Environment

Prepare your Azure environment for migration. This involves setting up Azure DevOps, creating an Azure App Service for hosting your application, and configuring necessary network components.

 

Step 3: Configure Continuous Integration/Continuous Deployment (CI/CD)

Implementing CI/CD is crucial for maintaining a consistent and reliable deployment process. Set up Jenkins or Azure DevOps pipelines to automate the build and deployment process.

 

Step 4: Migration

With the environment set up and CI/CD configured, you can now proceed to the migration of your IIS .NET applications. Use Azure’s migration tools or manually move the application code and data.

 

Step 5: Post-Migration Testing and Optimization

Post-migration, it’s important to thoroughly test your applications and optimize them for the new environment.

 

Leveraging Jenkins, GitHub, and Azure DevOps

These tools are instrumental in streamlining the migration process and maintaining a high standard of application performance post-migration.

 

Jenkins

Jenkins is an open-source automation server that can help to automate the non-human part of the software development process. It integrates with Azure, allowing you to manage and control the application development process from a centralized platform.

 

GitHub

GitHub hosts your application’s code, facilitating collaboration among teams. When integrated with Azure DevOps and Jenkins, you can automate the process of code integration and deployment.

 

Azure DevOps

Azure DevOps provides a range of services, including Azure Pipelines, which supports CI/CD, enabling automatic deployment of your applications.

 

FAQs

Q1: How can I ensure the security of my application during the migration process?

Azure provides numerous security tools and best practices to ensure data integrity during the migration.

 

Q2: What if my application performance degrades after the migration?

Azure provides tools for monitoring application performance and diagnosing issues, allowing you to optimize and improve performance post-migration.

 

Q3: Can I integrate other CI/CD tools with Azure?

Yes, Azure provides seamless integration with a range of CI/CD tools including Jenkins, GitHub Actions, and others.

 Conclusion

The transition of your IIS .NET applications from an on-premises environment to Azure doesn’t have to be daunting. By following a systematic approach and leveraging the capabilities of Azure DevOps, Jenkins, and GitHub, you can make this process seamless and efficient. Embrace the opportunities that Azure offers to optimize your application and bring it to new heights in the digital space.

Migrating OnPrem GitHub, Jenkins, IIS CI/CD Environment to Azure DevOps and Kubernetes

 Introduction

With the increasing popularity of cloud platforms, many organizations are moving their development and deployment operations to the cloud. Azure DevOps and Kubernetes are two popular cloud platforms that offer several benefits to businesses. If you’re still using OnPrem GitHub, Jenkins, IIS CI/CD environment, it’s time to migrate to Azure DevOps and Kubernetes.

 

This article will guide you through the process of migrating OnPrem GitHub, Jenkins, IIS CI/CD environment to Azure DevOps and Kubernetes. We will explore the benefits of using Azure DevOps and Kubernetes and the steps involved in the migration process.

 

 Why Move to Azure DevOps and Kubernetes?

 

Migrating to Azure DevOps and Kubernetes offers several benefits, including:

 

  1. Scalability: Azure DevOps and Kubernetes offer scalability, making it easy to increase or decrease resources as needed.

 

  1. Cost Savings: Azure DevOps and Kubernetes are cost-effective compared to OnPrem GitHub, Jenkins, IIS CI/CD environment.

 

  1. Automation: Azure DevOps and Kubernetes offer automation capabilities, reducing manual work and increasing efficiency.

 

  1. High Availability: Azure DevOps and Kubernetes offer high availability, ensuring that your applications are always available.

 

Steps Involved in Migrating OnPrem GitHub, Jenkins, IIS CI/CD Environment to Azure DevOps and Kubernetes

 

  1. Evaluate Your Current Environment: Before migrating to Azure DevOps and Kubernetes, evaluate your current environment. Identify the applications, services, and dependencies that need to be migrated.

 

  1. Create an Azure Account: To use Azure DevOps and Kubernetes, you need an Azure account. If you don’t have an account, create one.

 

  1. Set up Azure DevOps: Once you have an Azure account, set up Azure DevOps. This involves creating a new organization and project.

 

  1. Create a Kubernetes Cluster: To use Kubernetes, you need to create a Kubernetes cluster. You can create a cluster in Azure Kubernetes Service (AKS).

 

  1. Install Jenkins in Kubernetes Cluster: Install Jenkins in the Kubernetes cluster. This involves creating a Jenkins deployment and service.

 

  1. Migrate GitHub Repositories: Migrate the GitHub repositories to Azure DevOps. This involves creating a new Git repository in Azure DevOps and pushing the code.

 

  1. Migrate Jenkins Jobs: Migrate the Jenkins jobs to Azure DevOps. This involves creating new pipelines in Azure DevOps and configuring them.

 

  1. Migrate IIS Applications: Migrate the IIS applications to Kubernetes. This involves creating a Docker image of the application and deploying it to Kubernetes.

 

  1. Test and Validate: Once you have migrated all the applications and services, test and validate the new environment. Ensure that everything is working as expected.

 

 FAQs

 

Q: What is Azure DevOps?

A: Azure DevOps is a cloud-based platform that offers several services, including source control, build and release management, and project management.

 

Q: What is Kubernetes?

A: Kubernetes is a container orchestration platform that automates deployment, scaling, and management of containerized applications.

 

Q: Why Should I Migrate to Azure DevOps and Kubernetes?

A: Migrating to Azure DevOps and Kubernetes offers several benefits, including scalability, cost savings, automation, and high availability.

Conclusion

Migrating OnPrem GitHub, Jenkins, IIS CI/CD environment to Azure DevOps and Kubernetes is a necessary step for organizations that want to take advantage of the benefits offered by cloud platforms. The migration process involves evaluating your current environment, creating an Azure account, setting up Azure DevOps, creating a Kubernetes cluster, installing Jenkins in the Kubernetes cluster, migrating GitHub repositories and Jenkins jobs, migrating IIS applications, and testing and validating the new environment.

By migrating to Azure DevOps and Kubernetes, you can enjoy scalability, cost savings, automation, and high availability. Make the move and take your business to the next level.

Application Owners Self Service Solution

SelfService Application Administration on onpremise Enviroment

Infraself For The Application Owners

Hi ,

This time, I would like to tell you a small story about my application owners demands, request and a self service solution.

In my corporate company internal web site application owners stores their applications on-prem servers which I am in responsible infrastructure systems. Test, Development and Prod systems infrastructure are different but all of them on-prem. When the developers made some changes on the application configurations sometimes they can have a new code or updates about the application. They always came to me for the application service restart, application pool restart or even server restarts.

This is a annoying process for me and also for them. They are the responsible application but I have to take care of the application running status. Sometimes they can upload the wrong code or bugy codes. They need to update their codes and redeploy it to infrastructure (10) ten times in a day. That means I have to restart the services eleven (11) times in a day. No it was not  suitable  for  my working style !

In corporate rules application owners can’t have admin rights on any systems. So I need to find a solution for them and for my self.

I spoke to my manager about this process, he told me OK if you could find a suitable solution about it , he will gave me full support but with this conditions which are;

  1. With this solution they shouldn’t have  admin rights on any server,
  2. They shouldn’t have to have make a remote connection to any server,
  3. They could able to restart their own applications services or servers,
  4. On that systems every actions which they made ( restart , stop, start etc..) should be logged,
  5. They should not have get any admin rights user accounts information on that systems from any script or application.

So it seems a challenge, and yes Challenge Accepted !

What I got in my hands ;

  • All application working systems are Windows Servers versions,
  • All application owners willing to take care of the application full life cycle,
  •  Power shell scripts will be fine for all run windows operations.
  • Our MS licensing are giving me a freedom for all MS Products.

 How I solved my and application owners problem;

I have build a RDWeb Cluster systems for it. Two servers are accepting the connections with cluster build and they forwarding the RDP sessions to backend application sharing servers.  So with this operation users don’t know the RDP Servers. I have shared the Poweshell scripts via  RDWeb.

When users logon to RDWeb , if any powershell script shared with the user. Users can see the script. When click on the script , script is start to run on backend application server, so users can not see the script meta. I have sold the rest of the problems in side of the Powershell whic it was the easy part.

Here is the service restart script;

# Service Restart Script.
CLS
Function pause ($message)
{
# Check if running Powershell ISE
if ($psISE)
{
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show("$message")
}
else
{
Write-Host "$message" -ForegroundColor Darkgreen
$x = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
}

$Currentuser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$Username = 'Admin or service User Info'
$Password = 'Admin or service User Password'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$SecureString = $pass
# Users you password securly
$MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username,$SecureString 
filter timestamp {"$(Get-Date -Format G): $_"}
$owner = 'App server_Service_Restart Script'
$ServerName = 'Application Server Hostname'
$LogPath = '\\Shared\Log Path\to every\application sharing \_Restart.log'
$To = "application owner email"
$From = "from email"
$Subject = "Service Status Info"
$Cc = "monitoring team email grup"
$SmtpServer = "SMTP Server hostname"
$JobTime = Get-Date

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Select the Service !!!'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Select Your Service:'
$form.Controls.Add($label)

$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80

[void] $listBox.Items.Add('Service Name 1')
[void] $listBox.Items.Add('Service Name 2')
[void] $listBox.Items.Add('Service Name 2')
[void] $listBox.Items.Add('Service Name 2')
[void] $listBox.Items.Add('Service Name 2')

$form.Controls.Add($listBox)

$form.Topmost = $true

$result = $form.ShowDialog()

While ($true) {

if ($result -eq [System.Windows.Forms.DialogResult]::OK)

{
$x = $listBox.SelectedItem

$ITMessage = "If you have a trouble on $x please contact with ITI."


Write-Host Which operation would you like to run on Service $x ?
Write-Host ----------------------------
Write-Host 1 - Start 
Write-Host 2 - Stop
Write-Host 3 - Restart
Write-Host 4 - Check Service Status
Write-Host 5 - Kill the Service Process Manually
Write-Host 0 - Exit
Write-Host ----------------------------
Write-Host Please enter only number of the command . 
}

$command = Read-Host -Prompt 'Please enter the command number '

If ($command -eq 1) {

$sonuc = Invoke-command -credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($x) (Start-Service -InputObject $x -PassThru | select Status,Name,PSComputerName) } -ArgumentList $x
Write-Host $sonuc -ForegroundColor Green
Send-MailMessage -To $to -From $from -Cc $Cc -Subject $subject -Body "$x Service is started by $Currentuser via $owner at $JobTime on $ServerName " -SmtpServer $SmtpServer
Write-Output "$x Service is started by $Currentuser via $owner $ServerName"| timestamp >> $LogPath
Write-Host $ITMessage
pause "Press any key to continue"
CLS
}

ElseIf ($command -eq 2) {

$sonuc = Invoke-command -credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($x) (Stop-service -inputObject $x -PassThru | select Status,Name,PSComputerName) } -ArgumentList $x
Write-Host $sonuc -ForegroundColor Green
Send-MailMessage -To $to -From $from -Cc $Cc -Subject $subject -Body "$x Service is stoped by $Currentuser via $owner at $JobTime on $ServerName " -SmtpServer $SmtpServer
Write-Output "$x Service is stoped by $Currentuser via $owner on $ServerName"| timestamp >> $LogPath
Write-Host $ITMessage
pause "Press any key to continue"
CLS
}

ElseIf ($command -eq 3) {

$sonuc = Invoke-command -credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($x) (Restart-Service -inputObject $x -PassThru | select Status,Name,PSComputerName) } -ArgumentList $x
Write-Host $sonuc -ForegroundColor Green
Send-MailMessage -To $to -From $from -Cc $Cc -Subject $subject -Body "$x Service is restarted by $Currentuser via $owner at $JobTime on $ServerName" -SmtpServer $SmtpServer
Write-Output "$x Service is restarted by $Currentuser via $owner on $ServerName"| timestamp >> $LogPath
Write-Host $ITMessage
pause "Press any key to continue"
CLS
}

ElseIf ($command -eq 4) {

$sonuc = Invoke-command -credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($x) (Get-Service -inputObject $x | select -Property Status,Name,PSComputerName)} -ArgumentList $x
Write-Host $sonuc -ForegroundColor Green
Send-MailMessage -To $to -From $from -Cc $Cc -Subject $subject -Body "$x Service is checked by $Currentuser via $owner at $JobTime on $ServerName" -SmtpServer $SmtpServer
Write-Output "$x Service is checked by $Currentuser via $owner on $ServerName"| timestamp >> $LogPath
Write-Host $ITMessage
pause "Press any key to continue"
CLS
}

ElseIf ($command -eq 5) {

$id = Get-WmiObject -computername $Servername -credential $MySecureCreds -Class Win32_Service -Filter "Name LIKE '$x'" | Select-Object -ExpandProperty ProcessId
$procname = Invoke-command -credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($id) Get-Process -id $id |Select-Object -ExpandProperty Processname} -ArgumentList $id 
Write-Host $x Service Process Name is $procname and the process is killing now.
Invoke-command -credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($procname)get-process $procname | Stop-Process -Force -PassThru} -ArgumentList $procname
Write-Host $procname is killed and $x service is need to start again. -ForegroundColor Green 
Send-MailMessage -To $to -From $from -Cc $Cc -Subject $subject -Body "$x Service process is killed by $Currentuser via $owner at $JobTime on $ServerName " -SmtpServer $SmtpServer
Write-Output "$x Service process is killed by $Currentuser via $owner on $ServerName"| timestamp >> $LogPath
Write-Host $ITMessage
pause "Press any key to continue"
CLS
}

ElseIf ($command -eq 0) {
CLS
Exit
}

Else {
Write-Host "Please enter only number of the command !!! " -ForegroundColor Red
}
}
#App pool Restart Script
CLS
Function pause ($message)
{
# Check if running Powershell ISE
if ($psISE)
{
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show("$message")
}
else
{
Write-Host "$message" -ForegroundColor Darkgreen
$x = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
}

$Currentuser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$Username = 'Admin or Service Account'
$Password = 'Password of Admin or Service Account'
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$SecureString = $pass
# Users you password securly
$MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username,$SecureString 
filter timestamp {"$(Get-Date -Format G): $_"}
$owner = 'Log Name '
$ServerName = 'IIS Server Hostname'
$LogPath = 'Log full path \\share\logs\apppool_restart.log'
$To = "apppool owner email"
$From = "[email protected]"
$Subject = "Service Status Info"
$Cc = "monitoring team email"
$SmtpServer = "smtp server hostname or fqdn"
$JobTime = Get-Date

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form
$form.Text = 'Please select App !!!'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'IIS AppPool Select:'
$form.Controls.Add($label)

$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80

[void] $listBox.Items.Add('Web App Pool 1')
[void] $listBox.Items.Add('Web App Pool 2')
[void] $listBox.Items.Add('Web App Pool 3')
[void] $listBox.Items.Add('Web App Pool 4')
[void] $listBox.Items.Add('Web App Pool 5')
[void] $listBox.Items.Add('Web App Pool 6')


$form.Controls.Add($listBox)

$form.Topmost = $true

$result = $form.ShowDialog()

While ($true) {

if ($result -eq [System.Windows.Forms.DialogResult]::OK)

{
$x = $listBox.SelectedItem 

$ITMessage = "If you have a trouble on $x please contact with ITI."

Write-Host Which operation would you like to run on AppPool $x ?
Write-Host ----------------------------
Write-Host 1 - Start 
Write-Host 2 - Stop
Write-Host 3 - Restart
Write-Host 4 - Check Apppool status
Write-Host 0 - Exit
Write-Host ----------------------------
Write-Host Please enter only number of the command . 
}

$command = Read-Host -Prompt 'Please enter the command number '

If ($command -eq 1) {

$sonuc = Invoke-command –credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($x) (C:\Windows\System32\inetsrv\appcmd.exe start apppool "$x" ) } -ArgumentList $x
Write-Host $sonuc -ForegroundColor Green
end-MailMessage -To $to -From $from -Cc $Cc -Subject $subject -Body "$x App Pool is started by $Currentuser via $owner at $JobTime " -SmtpServer $SmtpServer
Write-Output "$x App Pool is started by $Currentuser via $owner"| timestamp >> $LogPath
Write-Host $ITMessage
pause "Press any key to continue"
CLS
}

ElseIf ($command -eq 2) {

$sonuc = Invoke-command –credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($x) (C:\Windows\System32\inetsrv\appcmd.exe stop apppool "$x" ) } -ArgumentList $x
Write-Host $sonuc -ForegroundColor Green
Send-MailMessage -To $to -From $from -Cc $Cc -Subject $subject -Body "$x App Pool is stoped by $Currentuser via $owner at $JobTime " -SmtpServer $SmtpServer
Write-Output "$x App Pool is stoped by $Currentuser via $owner"| timestamp >> $LogPath
Write-Host $ITMessage
pause "Press any key to continue"
CLS
}

ElseIf ($command -eq 3) {

$sonuc = Invoke-command –credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($x) (C:\Windows\System32\inetsrv\appcmd.exe recycle apppool "$x" ) } -ArgumentList $x
Write-Host $sonuc -ForegroundColor Green
Send-MailMessage -To $to -From $from -Cc $Cc -Subject $subject -Body "$x App Pool is restarted by $Currentuser via $owner at $JobTime " -SmtpServer $SmtpServer
Write-Output "$x App Pool is restarted by $Currentuser via $owner"| timestamp >> $LogPath
Write-Host $ITMessage
pause "Press any key to continue"
CLS
}

ElseIf ($command -eq 4) {

$sonuc = Invoke-command –credential $MySecureCreds -ComputerName $ServerName -ScriptBlock {param ($x) (C:\Windows\System32\inetsrv\appcmd.exe list apppool "$x" /text:state )} -ArgumentList $x
Write-Host $sonuc -ForegroundColor Green
Send-MailMessage -To $to -From $from -Cc $Cc -Subject $subject -Body "$x App Pool is checked by $Currentuser via $owner at $JobTime " -SmtpServer $SmtpServer
Write-Output "$x App Pool is checked by $Currentuser via $owner"| timestamp >> $LogPath
Write-Host $ITMessage
pause "Press any key to continue"
CLS
}

ElseIf ($command -eq 0) {
CLS
Exit
}

Else {
Write-Host "Please enter only number of the command !!! " -ForegroundColor Red
}
}

If you are familiar with powershell, I belive , I don’t need to explain the scripts steps.

With this powershell script they can able restart their own applications system services or web app pools . It is easy and simple solution for all of us.

In other hand that means less admin effort for me 🙂

Let me show you an example ;