Updated Azure Stack HOLs for TP3 Refresh (#123)
Updated general Azure Stack guidance, along with specific HOLs for Jenkins and Puppet.
|
@ -1,6 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Install Jenkins Dependencies
|
||||
add-apt-repository ppa:openjdk-r/ppa
|
||||
apt-get update
|
||||
apt-get upgrade -y
|
||||
apt-get install openjdk-7-jdk -y
|
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Update OS
|
||||
apt-get update
|
||||
# apt-get upgrade -y
|
||||
|
||||
# Validate input parameters
|
||||
if [[ !("$#" -eq 2) ]];
|
||||
then echo "Parameters missing for puppet enterprise configuration." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get parameters
|
||||
pe_version=$1
|
||||
console_pw=$2
|
||||
|
||||
# Configure for Puppet Enterprise version
|
||||
case $pe_version in
|
||||
2017.2.1)
|
||||
pe_url=https://pm.puppetlabs.com/puppet-enterprise/2017.2.1/puppet-enterprise-2017.2.1-ubuntu-16.04-amd64.tar.gz
|
||||
;;
|
||||
*)
|
||||
pe_url=https://pm.puppetlabs.com/puppet-enterprise/2017.2.1/puppet-enterprise-2017.2.1-ubuntu-16.04-amd64.tar.gz
|
||||
;;
|
||||
esac
|
||||
|
||||
# Set up variables
|
||||
pe_tar=${pe_url##*/}
|
||||
pe_folder=${pe_tar%%.tar.gz}
|
||||
|
||||
# Get installation package
|
||||
cd /tmp; wget -q ${pe_url}
|
||||
|
||||
# Unpack installation package
|
||||
tar -xf ${pe_tar}
|
||||
cd ${pe_folder}
|
||||
|
||||
# Create configuration file
|
||||
sed '/console_admin_password/c \
|
||||
"console_admin_password":"'$console_pw'"' conf.d/pe.conf > conf.d/azure-pe.conf
|
||||
|
||||
# Start the installation
|
||||
./puppet-enterprise-installer -c conf.d/azure-pe.conf
|
||||
sudo ./puppet-enterprise-installer -c conf.d/azure-pe.conf
|
||||
|
||||
exit 0
|
|
@ -15,9 +15,9 @@ As you can see, I've created entries for the Ubuntu base image, along with image
|
|||
Once you have those 3 items defined, you're at a point where you can used the [Azure Gallery Packager tool](http://www.aka.ms/azurestackmarketplaceitem) to package all of those respective files into a .azpkg file, that is then uploaded into your Azure Stack.
|
||||
|
||||
## Download an Example Package for the Base Ubuntu Image
|
||||
As mentioned earlier, it's much easier if you start from an esiting set of resources, and customize from there, so to help you understand the relationship between the core package files discussed above, you can download a set of files I've provided, already packaged as a .azpkg file. **Download it onto your MAS-CON01 machine**.
|
||||
As mentioned earlier, it's much easier if you start from an existing set of resources, and customize from there, so to help you understand the relationship between the core package files discussed above, you can download a set of files I've provided, already packaged as a .azpkg file. **Download it onto your MAS-CON01 machine**.
|
||||
|
||||
- [Download Base Image Package Files](/deploy/azurestack/instances/ubuntu_server_1404_base/Canonical.UbuntuServer.1.0.0.azpkg?raw=true)
|
||||
- [Download Base Image Package Files](/deploy/azurestack/instances/ubuntu_server_1604_base/Canonical.UbuntuServer.1.0.0.azpkg?raw=true)
|
||||
|
||||
1. Once downloaded, navigate to the folder containing your newly downloaded image, and **create a copy of the file**.
|
||||
2. Right click the new copy, and **rename to .zip**
|
||||
|
@ -56,28 +56,33 @@ Normally, once you've finished creating your respective files within your packag
|
|||
To save you time however, we'll just use the package we orginally downloaded earlier.
|
||||
|
||||
1. Navigate to your **Canonical.UbuntuServer.1.0.0.azpkg** file, you downloaded earlier
|
||||
2. Move it to a newly created folder **C:\MyMarketPlaceItems**.
|
||||
2. Move it to a newly created folder **C:\MyMarketplaceItems**.
|
||||
|
||||
It’s important to note that if you are going to use the package I have provided, you need to have used the following info when you uploaded your Ubuntu VHD image to the platform image repository earlier. Any differences, and the package I’m providing will not reference your uploaded image. If you used an exact copy of my PowerShell upload script, you're all set.
|
||||
|
||||
- Publisher "Canonical"
|
||||
- Offer "UbuntuServer"
|
||||
- SKU "1404-LTS"
|
||||
- SKU "16.04.3-LTS"
|
||||
|
||||
Now that we have the package ready to upload, we need *somewhere* in Azure Stack to upload it to. For that, we'll create a **storage account** that will be used to hold this package, and any others we upload in the future.
|
||||
|
||||
1. On MAS-CON01, connect to your Azure Stack via an **administrative PowerShell console**. If you're not still connected from the earlier steps, run the following:
|
||||
|
||||
``` powershell
|
||||
cd\
|
||||
cd C:\AzureStack-Tools-master\connect
|
||||
Import-Module .\AzureStack.Connect.psm1
|
||||
Add-AzureStackAzureRmEnvironment -AadTenant "<mydirectory>.onmicrosoft.com"
|
||||
Add-AzureRmAccount -EnvironmentName AzureStack
|
||||
Add-AzureStackAzureRmEnvironment -Name "AzureStackAdmin" -ArmEndpoint "https://adminmanagement.local.azurestack.external"
|
||||
$TenantID = Get-DirectoryTenantID -AADTenantName "<myaadtenant>.onmicrosoft.com or customdomain.com" -EnvironmentName AzureStackAdmin
|
||||
$UserName='<username@myaadtenant.onmicrosoft.com or username@customdomain.com>'
|
||||
$Password='<administrator or user password>'| `
|
||||
ConvertTo-SecureString -Force -AsPlainText
|
||||
$Credential= New-Object PSCredential($UserName,$Password)
|
||||
Login-AzureRmAccount -EnvironmentName "AzureStackAdmin" -TenantId $TenantID -Credential $Credential
|
||||
```
|
||||
2. Now, let's create the storage account to hold these packages. We'll call this **tenantartifacts** and store it in a dedicated **resource group** of the same name:
|
||||
|
||||
``` powershell
|
||||
$subscriptionid = (Get-AzureRmSubscription -SubscriptionName 'Default Provider Subscription').SubscriptionId
|
||||
$RG = New-AzureRmResourceGroup -Name tenantartifacts -Location local
|
||||
$StorageAccount = $RG | New-AzureRmStorageAccount -Name tenantartifacts -Type Standard_LRS
|
||||
```
|
||||
|
@ -85,8 +90,9 @@ Now that we have the package ready to upload, we need *somewhere* in Azure Stack
|
|||
|
||||
``` powershell
|
||||
$GalleryContainer = New-AzureStorageContainer -Name gallery -Permission Blob -Context $StorageAccount.Context
|
||||
$MarketPlaceAzpkg = $GalleryContainer | Set-AzureStorageBlobContent -File C:\MyMarketPlaceItems\Canonical.UbuntuServer.1.0.0.azpkg
|
||||
Add-AzureRMGalleryItem -SubscriptionId $subscriptionid -GalleryItemUri $MarketPlaceAzpkg.ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri -Apiversion "2015-04-01"
|
||||
$GalleryContainer | Set-AzureStorageBlobContent -File "C:\MyMarketplaceItems\Canonical.UbuntuServer.1.0.0.azpkg"
|
||||
$GalleryItemURI = (Get-AzureStorageBlob -Context $StorageAccount.Context -Blob 'Canonical.UbuntuServer.1.0.0.azpkg' -Container 'gallery').ICloudBlob.uri.AbsoluteUri
|
||||
Add-AzureRMGalleryItem -GalleryItemUri $GalleryItemURI -Verbose
|
||||
```
|
||||
|
||||
When successful, you should see a **StatusCode** of **Created**
|
||||
|
@ -95,12 +101,12 @@ When successful, you should see a **StatusCode** of **Created**
|
|||
|
||||
Go back and refresh the portal, and under New -> Virtual Machines -> See All, you should see your newly added Ubuntu marketplace item
|
||||
|
||||
![Ubuntu Marketplace Image](/deploy/azurestack/docs/media/UbuntuCreated.PNG)
|
||||
![Ubuntu Marketplace Image](/deploy/azurestack/docs/media/UbuntuCreated1604.PNG)
|
||||
|
||||
## Test Deployment of your Ubuntu Base Image
|
||||
You've successfully added a new marketplace item, but it's important to check that it works as expected. To do so, we'll walk through a UI deployment:
|
||||
|
||||
1. On MAS-CON01, from the Azure Stack Portal Dashboard, click on **New**, then **Virtual Machines**, then **Ubuntu Server 14.04-LTS**
|
||||
1. On MAS-CON01, from the Azure Stack Admin Portal Dashboard, click on **New**, then **Virtual Machines**, then **Ubuntu Server 16.04-LTS**
|
||||
2. Enter the basic details required - **username, password and a resource group name**.
|
||||
3. Optionally, select **Pin to Dashboard**, then click Create.
|
||||
4. The process should take around ~20 minutes, depending on your hardware.
|
||||
|
@ -120,4 +126,4 @@ When Putty opens, you'll need the Public IP address of the Ubuntu VM you deploye
|
|||
|
||||
# Next Step
|
||||
|
||||
Once successfully connected to your Ubuntu VM, you're now ready to move on to the [DevOps scenarios](/deploy/azurestack/docs/get_started_with_MRP).
|
||||
Once successfully connected to your Ubuntu VM, you're now ready to move on to the [DevOps scenarios](/deploy/azurestack/docs/get_started_with_MRP.md).
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Adding VM Images to Azure Stack#
|
||||
# Adding VM Images to Azure Stack
|
||||
|
||||
Azure Stack enables administrators to make VM images, such as their organization’s custom VHD, available to their tenants. Images can be referenced by Azure Resource Manager templates or added to the Azure Marketplace UI with the creation of a Marketplace item. As we saw previously, a Windows Server 2012 R2 image is included by default in the Azure Stack Technical Preview.
|
||||
Azure Stack enables administrators to make VM images, such as their organization’s custom VHD, available to their tenants. Images can be referenced by Azure Resource Manager templates or added to the Azure Marketplace UI with the creation of a Marketplace item. No images are included by default in the Azure Stack Technical Preview 3 Refresh.
|
||||
|
||||
An image can be added to your Azure Stack Platform Image Repository (PIR) in 2 ways - via the portal, or programmatically. We'll focus on the programmatical approach, specifically with PowerShell, as it's faster, and more repeatable. Plus, you can copy and paste my code ;-)
|
||||
|
||||
|
@ -16,11 +16,11 @@ For the purpose of our testing, we're going to focus on Linux images. Microsoft
|
|||
* [SuSE](https://download.suse.com/Download?buildid=VCFi7y7MsFQ~)
|
||||
* [Ubuntu 14.04 LTS](https://partner-images.canonical.com/azure/azure_stack/) / [Ubuntu 16.04 LTS](http://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.vhd.zip)
|
||||
|
||||
We'll be focusing on **Ubuntu 14.04 LTS**, so that's the one you should be downloading too. When you click on the Ubuntu 14.04 LTS link above, you'll be taken to a page with a list of builds for that particular release. Choose the one at the bottom of the list, which typically corresponds to the newest of the builds. If you accept the default name, and save location, you'll end up with a 300+MB zip file, located in the downloads folder.
|
||||
We'll be focusing on **Ubuntu 16.04 LTS**, so that's the one you should be downloading too. When you click on the Ubuntu 16.04 LTS link above, you'll automatically be downloading the latest build. If you accept the default name, and save location, you'll end up with a 490+MB zip file, located in the downloads folder.
|
||||
|
||||
Once downloaded, extract the zip file, to end up with a single 30GB VHD, with the name **trusty-server-cloudimg-amd64-disk1.vhd**.
|
||||
Once downloaded, extract the zip file, to end up with a single 30GB VHD, with the name **xenial-server-cloudimg-amd64-disk1.vhd**.
|
||||
|
||||
1. Rename the VHD file to Ubuntu1404LTS.vhd
|
||||
1. Rename the VHD file to Ubuntu1604LTS.vhd
|
||||
2. Move the file to a new folder called C:\Images
|
||||
3. Optional - to free up space, delete the original ZIP file you just downloaded.
|
||||
|
||||
|
@ -34,18 +34,37 @@ Before we can begin adding an image to the Azure Stack PIR, we'll need to be abl
|
|||
``` PowerShell
|
||||
Get-PSRepository
|
||||
```
|
||||
2. Run the following command to install the AzureRM module:
|
||||
2. Before installing the required version, make sure that you uninstall any existing Azure PowerShell modules. To uninstall, close all the active PowerShell sessions and run the following command:
|
||||
|
||||
``` PowerShell
|
||||
Install-Module -Name AzureRM -RequiredVersion 1.2.6 -Scope CurrentUser -Force -AllowClobber
|
||||
```
|
||||
> *-Scope CurrentUser* is optional. If you want more than the current user to have access to the modules, use an elevated command prompt and leave off the *Scope* parameter. -Force and -AllowClobber will ensure that any existing AzureRM modules are replaced and updated.
|
||||
|
||||
3. To confirm the installation of AzureRM modules, execute the following commands:
|
||||
``` PowerShell
|
||||
Get-Command -Module AzureRM.AzureStackAdmin
|
||||
Get-Module -ListAvailable | where-Object {$_.Name -like "Azure*"} | Uninstall-Module
|
||||
```
|
||||
|
||||
Once verified, we need to ensure we have the relevant tools in place to connect to Azure Stack via PowerShell. These could also be used for Azure, but may lack some of the latest Azure features. The tools are all [hosted on GitHub](https://github.com/Azure/AzureStack-Tools). To grab them, run the following in an elevated PowerShell console on MAS-CON01:
|
||||
3. Azure Stack compatible AzureRM modules are installed through API version profiles. To learn about API version profiles and the cmdlets provided by them, refer to the manage API version profiles article. The AzureRM.Bootstrapper module provides PowerShell commands that are required to work with API version profiles. Use the following command to install the AzureRM.Bootstrapper module:
|
||||
|
||||
``` PowerShell
|
||||
Install-Module -Name AzureRm.BootStrapper
|
||||
```
|
||||
|
||||
4. Run the following command to install the 2017-03-09-profile version of the AzureRM modules for Compute, Storage, Network, Key Vault etc:
|
||||
|
||||
``` PowerShell
|
||||
Use-AzureRmProfile -Profile 2017-03-09-profile
|
||||
```
|
||||
|
||||
5. In addition to the AzureRM modules, you should also install the Azure Stack-specific PowerShell modules such as AzureStackAdmin, and AzureStackStorage by running the following command:
|
||||
|
||||
``` PowerShell
|
||||
Install-Module -Name AzureStack -RequiredVersion 1.2.9
|
||||
```
|
||||
|
||||
6. To confirm the installation, run the following command:
|
||||
|
||||
``` PowerShell
|
||||
Get-Module -ListAvailable | where-Object {$_.Name -like "Azure*"}
|
||||
```
|
||||
|
||||
If the installation is successful, the AzureRM and AzureStack modules are displayed in the output. Once verified, we need to ensure we have the relevant tools in place to connect to Azure Stack via PowerShell. These could also be used for Azure, but may lack some of the latest Azure features. The tools are all [hosted on GitHub](https://github.com/Azure/AzureStack-Tools). To grab them, run the following in an elevated PowerShell console on MAS-CON01:
|
||||
|
||||
``` PowerShell
|
||||
cd\
|
||||
|
@ -53,20 +72,43 @@ Invoke-Webrequest https://github.com/Azure/AzureStack-Tools/archive/master.zip -
|
|||
Expand-Archive master.zip -DestinationPath . -Force
|
||||
cd AzureStack-Tools-master\connect
|
||||
Import-Module .\AzureStack.Connect.psm1
|
||||
Set-ExecutionPolicy Unrestricted
|
||||
```
|
||||
### Connect to Azure Stack
|
||||
With the Azure Stack connection module now imported, you can use the following commands to connect to your Azure Stack. Note, AzureRM cmdlets can be targeted at multiple Azure clouds such as Azure China, Government, and Azure Stack.
|
||||
To target your Azure Stack instance, an AzureRM environment needs to be registered as follows.
|
||||
|
||||
```powershell
|
||||
Add-AzureStackAzureRmEnvironment -AadTenant "<mydirectory>.onmicrosoft.com"
|
||||
```
|
||||
The AadTenant parameter above specifies the directory that was used when deploying Azure Stack. After registering, AzureRM environment cmdlets can be easily targeted at your Azure Stack instance. For example:
|
||||
**Note** - The below instructions are based on the use of Azure Active Directory for login. If you chose to install with Active Directory Federation Services instead, please use the [documentation](https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-powershell-configure) to connect.
|
||||
|
||||
```powershell
|
||||
Add-AzureRmAccount -EnvironmentName AzureStack
|
||||
``` Powershell
|
||||
Add-AzureStackAzureRmEnvironment -Name "AzureStackAdmin" -ArmEndpoint "https://adminmanagement.local.azurestack.external"
|
||||
```
|
||||
You will be prompted for the account login including two factor authentication if it is enabled in your organization. You can also log in with a service principal using appropriate parameters of the Add-AzureRmAccount cmdlet. Keep this PowerShell console window open, for use later.
|
||||
|
||||
Get the GUID value of the Active Directory(AD) tenant that is used to deploy the Azure Stack. Note, you'll need to change the AADTenantName to reflect your AAD Tenant used for installation.
|
||||
|
||||
``` Powershell
|
||||
$TenantID = Get-DirectoryTenantID -AADTenantName "<myaadtenant>.onmicrosoft.com" -EnvironmentName AzureStackAdmin
|
||||
```
|
||||
|
||||
After the AzureRM environment is registered to target the Azure Stack instance, you can use all the AzureRM commands in your Azure Stack environment. Use the following steps to sign in your Azure Stack environment:
|
||||
|
||||
``` Powershell
|
||||
$UserName='<Username of the service administrator or user account>'
|
||||
$Password='<administrator or user password>'| `
|
||||
ConvertTo-SecureString -Force -AsPlainText
|
||||
$Credential= New-Object PSCredential($UserName,$Password)
|
||||
```
|
||||
|
||||
The above will store the store the administrator or user account's credentials in a variable. We'll be using the administrator's account to keep things simple, so just replace those details in the PowerShell commands above. You'll then use the following commands to log into the environment:
|
||||
|
||||
``` Powershell
|
||||
Login-AzureRmAccount `
|
||||
-EnvironmentName "AzureStackAdmin" `
|
||||
-TenantId $TenantID `
|
||||
-Credential $Credential
|
||||
```
|
||||
|
||||
Once you've run through all of these commands, you should be successfully connected.
|
||||
|
||||
**Note, if you need info on connecting to your Azure Stack via VPN, see the [Azure Stack documentation](https://github.com/Azure/AzureStack-Tools/tree/master/Connect).**
|
||||
|
||||
|
@ -75,15 +117,25 @@ Once logged in, you're ready to start adding images to your Azure Stack.
|
|||
## Add VM Image to Platform Image Repository with PowerShell
|
||||
The first thing we'll need to do to upload an image with PowerShell, is import the Compute module, from our tools folder.
|
||||
|
||||
```powerShell
|
||||
``` PowerShell
|
||||
cd ..
|
||||
cd ComputeAdmin
|
||||
cd .\ComputeAdmin\
|
||||
Import-Module .\AzureStack.ComputeAdmin.psm1
|
||||
```
|
||||
We're then ready to push our Ubuntu image that we downloaded earlier, into our Azure Stack PIR. Now, the code below is accurate assuming you used the same naming conventions I did, earlier. If not, adjust as necessary.
|
||||
|
||||
```powerShell
|
||||
Add-VMImage -publisher "Canonical" -offer "UbuntuServer" -sku "1404-LTS" -version "1.0.0" -osType Linux -osDiskLocalPath 'C:\Images\Ubuntu1404LTS.vhd' -tenantID <myaadtenant>.onmicrosoft.com -CreateGalleryItem $false
|
||||
``` PowerShell
|
||||
Add-VMImage `
|
||||
-publisher "Canonical" `
|
||||
-offer "UbuntuServer" `
|
||||
-sku "16.04.3-LTS" `
|
||||
-version "1.0.0" `
|
||||
-osType Linux `
|
||||
-osDiskLocalPath 'C:\Images\Ubuntu1604LTS.vhd' `
|
||||
-TenantId $TenantID `
|
||||
-EnvironmentName "AzureStackAdmin" `
|
||||
-azureStackCredentials $Credential `
|
||||
-CreateGalleryItem $false
|
||||
```
|
||||
The command above does the following:
|
||||
|
||||
|
@ -92,40 +144,25 @@ The command above does the following:
|
|||
* Adds the VM image to the VM image repository
|
||||
* Removes the temporary storage account
|
||||
|
||||
You'll notice at the end of the command, there was a parameter called **-CreateGalleryItem**, and the value for this, I declared as false. By default, when you run this command without using this parameter, a default marketplace item will be created for this particular image. If you recall, earlier when we deployed our Windows Server 2012 R2 VM, this was created from a marketplace image, which had an icon, desciption and more. For this Ubuntu image, we'll skip the marketplace creation for now, and will create a more professional, complete one later. Once you've executed the command, leave the PowerShell window open for later.
|
||||
You'll notice at the end of the command, there was a parameter called **-CreateGalleryItem**, and the value for this, I declared as false. By default, when you run this command without using this parameter, a default marketplace item will be created for this particular image. A marketplace item would consist of a logo, description etc, and deployable graphically via the Portal. For this Ubuntu image, we'll skip the marketplace creation for now, and will create a more professional, complete one later. Once you've executed the command, leave the PowerShell window open for later.
|
||||
|
||||
If you're interested in understanding a bit more about the other parameters used with the command above, [check out the docs](https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-add-vm-image).
|
||||
|
||||
## Explore the Platform Image Repository
|
||||
With the upload complete, it's important to confirm that the image now exist in the PIR. To do so, follow these steps:
|
||||
|
||||
1. Open the Azure Stack Portal and log in as the Service Administrator.
|
||||
1. Open the Azure Stack Admin Portal and log in as the Service Administrator.
|
||||
2. On the dashboard, click on the **Region Management** tile.
|
||||
3. In the Region Management blade, click on **local** and then in the Resource Providers box, click on **Compute**.
|
||||
4. In the Compute blade, under Content, click on **VM Images**.
|
||||
5. In the VM Images blade, you should see 2 images listed. The original Windows Server image, and the newly added Ubuntu image.
|
||||
5. In the VM Images blade, you should see your Ubuntu image listed.
|
||||
|
||||
![Image Added](/deploy/azurestack/docs/media/VM%20Images%20Complete.PNG)
|
||||
![Image Added](/deploy/azurestack/docs/media/VMImages.PNG)
|
||||
|
||||
6. Close all open blades and return to the dashboard.
|
||||
|
||||
## *Important - Add Diagnostic Extension to enable Linux Monitoring
|
||||
The extension required to monitor Linux VMs, didn't ship in the box with the Azure Stack Technical Preview 2, so we'll quickly add it to avoid any issues later. On the **Azure Stack POC Host machine**, execute the following steps, from an **administrative PowerShell console**.
|
||||
|
||||
```powershell
|
||||
New-Item C:\ClusterStorage\Volume1\Shares\SU1_Infrastructure_1\CRP\GuestArtifactRepository\IaaSDiagnosticsLinux -Type directory
|
||||
Invoke-WebRequest https://raw.githubusercontent.com/bgelens/BlogItems/master/Microsoft.OSTCExtensions.LinuxDiagnostic_2.3.9009.zip -OutFile C:\ClusterStorage\Volume1\Shares\SU1_Infrastructure_1\CRP\GuestArtifactRepository\IaaSDiagnosticsLinux\Microsoft.OSTCExtensions.LinuxDiagnostic_2.3.9009.zip
|
||||
Invoke-WebRequest https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/deploy/azurestack/customscripts/linux_extension/manifest.json -OutFile C:\ClusterStorage\Volume1\Shares\SU1_Infrastructure_1\CRP\GuestArtifactRepository\IaaSDiagnosticsLinux\manifest.json
|
||||
```
|
||||
With those commands executed, hop back over to the MAS-CON01 machine, and in your administrative PowerShell console, run the following:
|
||||
|
||||
```powershell
|
||||
Get-AzureRmVMExtensionImage -PublisherName Microsoft.OSTCExtensions -Location local -Type LinuxDiagnostic
|
||||
```
|
||||
You should receive an output, and not an exception. If so, you're ready to move on.
|
||||
|
||||
# Next Step
|
||||
You're now ready to start the deployment of the Parts Unlimited MRP environment, or explore any one of the DevOps scenarios provided within this documetation. These include CI/CD with Jenkins, Configuration Management with Chef, and Configuration Management with Puppet, with more to come in the future. Check out the [Getting Started with Parts Unlimited](/deploy/azurestack/docs/get_started_with_MRP) page to go forward.
|
||||
You're now ready to start the deployment of the Parts Unlimited MRP environment, or explore any one of the DevOps scenarios provided within this documetation. These include CI/CD with Jenkins, Configuration Management with Chef, and Configuration Management with Puppet, with more to come in the future. Check out the [Getting Started with Parts Unlimited](/deploy/azurestack/docs/get_started_with_MRP.md) page to go forward.
|
||||
|
||||
If you're interested in understanding how to create more professional marketplace items, so that your users can deploy the base Ubuntu image, along with any other future images, direct from the Azure Stack marketplace, then read on...
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# Connecting to Azure Stack#
|
||||
# Connecting to Azure Stack
|
||||
|
||||
With your Azure Stack deployed, you should be logged in to the Azure Stack POC host, ready to use the environment. Now, in order to use the environment correctly, you will need to log into the MAS-CON01 virtual machine. This machine is your primary machine for administering, deploying and managing the Azure Stack.
|
||||
|
||||
## Connect with Remote Desktop
|
||||
With a Remote Desktop connection, a single concurrent user can work with the portal to manage resources. You can also use tools on the MAS-CON01 virtual machine.
|
||||
With a Remote Desktop connection, up to two concurrent (different) users can work with the portal to manage resources. You can also use tools on the MAS-CON01 virtual machine.
|
||||
|
||||
1. Log in to the Azure Stack POC physical machine.
|
||||
2. Open a Remote Desktop Connection and connect to MAS-CON01. Enter **AzureStack\AzureStackAdmin** as the username, and the administrative password you provided during Azure Stack setup.
|
||||
3. On the MAS-CON01 desktop, open Server Manager, click **Local Server**, turn off Internet Explorer Enhanced Security, and then close Server Manager.
|
||||
4. Double-click **Microsoft Azure Stack Portal** icon (https://portal.azurestack.local/) to open the portal
|
||||
4. Double-click **Microsoft Azure Stack Admin Portal** icon (https://adminportal.local.azurestack.external/) to open the portal
|
||||
5. Log in using the Azure Active Directory credentials specified during installation.
|
||||
|
||||
Once you've successfully connected, you're free to explore the Azure Stack environment.
|
||||
|
@ -25,34 +25,6 @@ It's easier if you do this now, rather than later. It'll make things easier when
|
|||
3. In the Internet Explorer Enhanced Security Configuration window, for Administrators, select **Off** and click **OK**.
|
||||
4. Close Server Manager.
|
||||
|
||||
## Deploy a Virtual Machine
|
||||
|
||||
In order to test the Azure Stack functionality, a simple test would be to deploy a virtual machine.
|
||||
|
||||
1. From inside the portal, click **New**, and then **Virtual Machines**.
|
||||
2. In the Virtual Machines blade, click **See all**.
|
||||
3. In the new Virtual Machines blade, you'll be presented with all of the choices you can make, for deployment within your Azure Stack. As it stands, by default, there is only a standalone Windows Server 2012 R2 virtual machine, or an Availability Set. Select **WindowsServer-2012-R2-Datacenter** then click **Create**.
|
||||
4. In the Create Virtual Machine blade, provide the basic information and click **OK**.
|
||||
|
||||
![Enter Basic Info](/deploy/azurestack/docs/media/CreateVMBasic.PNG)
|
||||
5. Choose a virtual machine size for your deployment. It's recommended just to go with the default **A2 standard**, then click **Select**.
|
||||
6. Configure any optional features you wish to change. For the purposes of this test, simply accept the defaults and click **OK**.
|
||||
7. Review the final summary, wait for validation, and then click **OK** to start the deployment.
|
||||
|
||||
This deployment may take a few minutes, and will depend on your hardware. Once complete, you should see a new tile on your dashboard.
|
||||
|
||||
![VM Deployed](/deploy/azurestack/docs/media/VMdeployed.PNG)
|
||||
|
||||
Whilst it's great to have a Windows Server to deploy onto Azure Stack, the real power is when you start to provide your own, customized images that can be deployed within the environment. These could be standard base Linux distro images, or something more customized, to include apps and other features that are enabled during the deployment.
|
||||
|
||||
# Next Step
|
||||
|
||||
In the next step, we'll [add a new VM image](/deploy/azurestack/docs/adding_vm_images.md), that we'll use for our ongoing tasks to evaluate key DevOps tooling on Azure Stack.
|
||||
|
||||
## Optional - Clean Up VM Deployment
|
||||
|
||||
If you're not going to use the previously deployed Windows Server VM, follow these steps to remove it from your Azure Stack environment:
|
||||
|
||||
1. In the Azure Stack Portal, click **Resource Groups**
|
||||
2. In the list of Resource Groups, find your entry that you created during the Windows Server VM deployment, and on the far-right of the list, click the 3 dots **...** then choose **Delete**.
|
||||
3. In the new blade, enter the name of the Resource Group, and click **Delete**. This will clean up all of the artifacts from your deployment. It will take a few minutes, and you will receive a notification when complete.
|
||||
|
|
|
@ -0,0 +1,368 @@
|
|||
# Continuous Deployment with Jenkins
|
||||
|
||||
In this lab, you will learn how to deploy the Parts Unlimited MRP App in an automated fashion onto a Linux VM with no agent.
|
||||
After this lab, you will have a working pipeline in Jenkins that will build, test, and deploy the Parts Unlimited MRP app to a Virtual Machine in Azure Stack.
|
||||
|
||||
## Pre-Requisites:
|
||||
|
||||
- Completion of the lab [Set up Parts Unlimited MRP with Jenkins](/deploy/azurestack/docs/jenkins_setup.md)
|
||||
- Completion of the [Continuous Integration with Jenkins lab](/deploy/azurestack/docs/jenkins_CI.md)
|
||||
|
||||
## Overview:
|
||||
During this lab, we will implement the continuous delivery of the artifacts that we have built in the previous lab.
|
||||
|
||||
## Install the SSH Agent plugin
|
||||
In this task, we are going to install the ssh-agent plugin on Jenkins. This plugin will allow Jenkins to connect via ssh to the target machine during the deployment or the artifacts.
|
||||
|
||||
**1.** Switch to the SSH session to your Jenkins server (or open a new one if you have closed the one from the previous lab) and type the following command
|
||||
```
|
||||
sudo java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s http://Jenkins:Passw0rd@127.0.0.1:8080/ install-plugin ssh-agent
|
||||
```
|
||||
The result should be
|
||||
```
|
||||
Installing ssh-agent from update center
|
||||
```
|
||||
|
||||
**2.** Restart the Jenkins server so that the newly installed plugin becomes active.
|
||||
|
||||
From the Jenkins Master, type the following command:
|
||||
```
|
||||
sudo java -jar /var/cache/jenkins/war/WEB-INF/jenkins-cli.jar -s http://Jenkins:Passw0rd@localhost:8080/ safe-restart
|
||||
```
|
||||
|
||||
Keep your ssh session open.
|
||||
|
||||
## Create a pair of SSH keys
|
||||
In this taks, we will create a pair of ssh keys to be able to automatically connect to the deployment server.
|
||||
|
||||
**1.** Type the following command:
|
||||
```
|
||||
ssh-keygen
|
||||
```
|
||||
|
||||
**2.** Press **Enter** to leave the default values for the filename and the passphrase.
|
||||
|
||||
![Creating a new ssh-rsa keypair](<../../../docs/assets/jenkins/ssh_key.png>)
|
||||
|
||||
**3.** Copy the private key file to /var/lib/jenkins/.ssh by typing the following commands:
|
||||
|
||||
```
|
||||
sudo mkdir /var/lib/jenkins/.ssh/
|
||||
sudo chown jenkins:jenkins /var/lib/jenkins/.ssh
|
||||
sudo cp .ssh/id_rsa /var/lib/jenkins/.ssh/id_rsa
|
||||
sudo chown jenkins:jenkins /var/lib/jenkins/.ssh/id_rsa
|
||||
```
|
||||
|
||||
**4.** Create a Jenkins credentials
|
||||
|
||||
Navigate to
|
||||
```
|
||||
http://ip_address_of_your_jenkinsmaster:8080/credentials/store/system/domain/_/newCredentials
|
||||
```
|
||||
|
||||
Because of the restart, you will have to authenticate again with the following credentials:
|
||||
* Username = Jenkins
|
||||
* Password = Passw0rd
|
||||
|
||||
|
||||
**5.** Enter the values for the credentials as follows
|
||||
|
||||
* Select **SSH Username with private key** for the Kind
|
||||
* Leave the scope as "Global"
|
||||
* Type **mrpadmin** for the Username
|
||||
* Select **From the Jenkins master ~/.ssh**
|
||||
* Leave the Passphrase empty
|
||||
* Type **mrpadmin** for the ID
|
||||
|
||||
Click **OK**
|
||||
|
||||
![Adding SSH key to Jenkins](<../../../docs/assets/jenkins/jenkins_addsshkey.png>)
|
||||
|
||||
## Create the VM to run the Parts Unlimited MRP application
|
||||
|
||||
Now, you have 2 options for deployment.
|
||||
|
||||
1. **ARM Template & Custom Deployment** -> for this option, you will perform a new custom template deployment from Azure Stack, using a JSON file that will be provided for you. You will enter a number of key values for the parameters, and then deploy. **This is the quicker option**.
|
||||
2. **Create a Custom Marketplace Item for Deployment** -> for this option, in the same way you (optionally) added an Ubuntu 16.04.3-LTS item to the Azure Stack Marketplace, you will add a new .azpkg to your Azure Stack, and configure the deployment from this, providing the same parameters as per option 1.
|
||||
|
||||
**The end result of both of these options is the same, however if you'd like to populate your gallery with more items, use option 2.**
|
||||
|
||||
### *Option 1 - ARM Template & Custom Deployment
|
||||
If you're not interested in creating a Marketplace item for 'Parts Unlimited MRP with SSH', then this quick and easy approach should make things, well, quick and easy for you!
|
||||
|
||||
Firstly, we need the SSH key to use with this new virtual machine. To obtain this, go back to your SSH session, and run:
|
||||
|
||||
```
|
||||
cat ./.ssh/id_rsa.pub
|
||||
```
|
||||
|
||||
Select the returned text, and copy it. We will use it later.
|
||||
|
||||
![Copy SSH public key](<../../../docs/assets/jenkins/copy_sshpublickey.png>)
|
||||
|
||||
Then, from your MAS-CON01 machine, you need to click on the button below to deploy the MRP virtual machine, and fill in the parameter fields. The link should open the Azure Stack portal, and if you're not already logged in, it'll prompt you for your Azure Stack credentials, then take you immediately to the custom template blade.
|
||||
|
||||
<a href="https://adminportal.local.azurestack.external/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FMicrosoft%2FPartsUnlimitedMRP%2Fmaster%2Fdeploy%2Fazurestack%2Finstances%2Fparts_unlimited_SSH_mrp_base%2FPartsUnlimitedSSH.Ubuntu1604%2FDeploymentTemplates%2FPartsUnlimitedSSHMRP.json" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/azurestack/docs/media/DeployToStack.png"/>
|
||||
</a>
|
||||
|
||||
You'll need to enter information for the following fields:
|
||||
- **ADMINPUBLICKEY** - Paste the string that you have copied earlier.
|
||||
- **MRPDNSNAMEFORPUBLICIP** - for testing purposes, use **mrp-deploy**.
|
||||
- **Resource Group** - for testing purposes, use **mrp-deploy**.
|
||||
- **Location** - seeing as this is Azure Stack, you'll just be able to choose local in the current technical preview.
|
||||
|
||||
![Jenkins Deployment](/deploy/azurestack/docs/media/MRPDeploy.PNG)
|
||||
|
||||
If you're interested in taking a deeper look at the ARM template that is used for deployment, you could either **click Edit Template** within the custom template deployment blade, and that will present the template that will be used for the deployment, or alternatively, you could **[grab the ARM template from here](/deploy/azurestack/instances/parts_unlimited_SSH_mrp_base/PartsUnlimitedSSH.Ubuntu1604/DeploymentTemplates/PartsUnlimitedSSHMRP.json)**
|
||||
|
||||
Depending on your hardware, the deployment of the key artifacts, the virtual machine, and its respective automated configuration, may take a while. Expect around 20-30 mins for the deployment, unless you have new hardware, and a bank of SSDs for storage!
|
||||
|
||||
Once the deployment has completed, you're ready to proceed with the lab.
|
||||
|
||||
### *Option 2 - Create a Custom Marketplace Item for Deployment
|
||||
If you are interested in adding a custom marketplace item to your Azure Stack marketplace, then these steps will help. I've already made the package for you, so you should just be able to follow these steps, and import it right into your Azure Stack.
|
||||
|
||||
As we saw earlier, when we [added our Ubuntu base image to the Azure Stack marketplace](/deploy/azurestack/docs/add_marketplace_item.md), things are much easier when something is packaged for you, so to start things off, pull down the .azpkg file for our Parts Unlimited MRP with SSH machine, that I've stored on GitHub. From yor **MAS-CON01** machine, do the following:
|
||||
|
||||
- [Download Parts Unlimited MRP with SSH Package](https://github.com/Microsoft/PartsUnlimitedMRP/raw/master/deploy/azurestack/instances/parts_unlimited_SSH_mrp_base/PartsUnlimited.MRPSSH.1.0.0.azpkg)
|
||||
|
||||
1. Navigate to your **PartsUnlimited.MRPSSH.1.0.0.azpkg** file, you downloaded earlier
|
||||
2. Move it to a newly created folder **C:\MyMarketPlaceItems**.
|
||||
|
||||
It’s important to note that if you are going to use the package I have provided, you need to have used the following info when you uploaded your Ubuntu base VHD image to the platform image repository [earlier](/deploy/azurestack/docs/adding_vm_images.md). Any differences, and the package I’m providing will not reference your uploaded image. If you used an exact copy of my PowerShell upload script, you're all set.
|
||||
|
||||
- Publisher "Canonical"
|
||||
- Offer "UbuntuServer"
|
||||
- SKU "16.04.3-LTS"
|
||||
|
||||
Now that we have the package ready to upload, we need *somewhere* in Azure Stack to upload it to. Fortunately, we [created a storage account for this very purpose earlier](/deploy/azurestack/docs/add_marketplace_item.md#uploading-a-package-to-azure-stack), so we'll use the same storage account for this package.
|
||||
|
||||
1. Connect to your Azure Stack via an **administrative PowerShell console**. If you're not still connected from the earlier steps, run the following:
|
||||
|
||||
``` powershell
|
||||
cd\
|
||||
cd C:\AzureStack-Tools-master\connect
|
||||
Import-Module .\AzureStack.Connect.psm1
|
||||
Add-AzureStackAzureRmEnvironment -Name "AzureStackAdmin" -ArmEndpoint "https://adminmanagement.local.azurestack.external"
|
||||
$TenantID = Get-DirectoryTenantID -AADTenantName "<myaadtenant>.onmicrosoft.com or customdomain.com" -EnvironmentName AzureStackAdmin
|
||||
$UserName='<username@myaadtenant.onmicrosoft.com or username@customdomain.com>'
|
||||
$Password='<administrator or user password>'| `
|
||||
ConvertTo-SecureString -Force -AsPlainText
|
||||
$Credential= New-Object PSCredential($UserName,$Password)
|
||||
Login-AzureRmAccount -EnvironmentName "AzureStackAdmin" -TenantId $TenantID -Credential $Credential
|
||||
```
|
||||
|
||||
2. Now, let's access the storage account to hold this package. If you recall, we named the storage account **tenantartifacts** and this is located in a dedicated **resource group** of the same name:
|
||||
|
||||
``` powershell
|
||||
$StorageAccount = Get-AzureRmStorageAccount -ResourceGroupName tenantartifacts -Name tenantartifacts
|
||||
$GalleryContainer = Get-AzureStorageContainer -Name gallery -Context $StorageAccount.Context
|
||||
```
|
||||
3. With the resource group, storage account and gallery container now accessible, we can push our new Jenkins marketplace package into Azure Stack.
|
||||
|
||||
``` powershell
|
||||
$GalleryContainer | Set-AzureStorageBlobContent -File "C:\MyMarketPlaceItems\PartsUnlimited.MRPSSH.1.0.0.azpkg"
|
||||
$GalleryItemURI = (Get-AzureStorageBlob -Context $StorageAccount.Context -Blob 'PartsUnlimited.MRPSSH.1.0.0.azpkg' -Container 'gallery').ICloudBlob.uri.AbsoluteUri
|
||||
Add-AzureRMGalleryItem -GalleryItemUri $GalleryItemURI -Verbose
|
||||
```
|
||||
|
||||
When successful, you should see a **StatusCode** of **Created**
|
||||
|
||||
![Successful Upload](/deploy/azurestack/docs/media/PSCreated.PNG)
|
||||
|
||||
Go back and refresh the portal, and under **New -> Virtual Machines -> See All**, you should see your newly added Parts Unlimited MRP with SSH marketplace item
|
||||
|
||||
![MRP VM added to Marketplace](/deploy/azurestack/docs/media/MRPwithSSHMarketplace.PNG)
|
||||
|
||||
With your newly created marketplace item created and pushed to the Azure Stack Marketplace, we're ready to deploy an instance of the environment.
|
||||
|
||||
1. On the **MAS-CON01** machine, in your Azure Stack portal, click on **New**, then **Virtual Machines**, then **See all**.
|
||||
2. Select the **Parts Unlimited MRP with SSH** item in the marketplace, and click **Create**.
|
||||
3. You'll need to enter information for the following fields:
|
||||
- **ADMINPUBLICKEY** - Paste the string that you have copied earlier.
|
||||
- **MRPDNSNAMEFORPUBLICIP** - for testing purposes, use **mrp-deploy**.
|
||||
- **Resource Group** - for testing purposes, use **mrp-deploy**.
|
||||
- **Location** - seeing as this is Azure Stack, you'll just be able to choose local in the current technical preview.
|
||||
|
||||
Once you've filled in the fields, it should look like this:
|
||||
|
||||
![Jenkins Deployment](/deploy/azurestack/docs/media/MRPDeploy.PNG)
|
||||
|
||||
4. Click **OK** to confirm the parameters, and then **Create** to start the deployment.
|
||||
|
||||
Depending on your hardware, the deployment of the key artifacts, the virtual machine, and its respective automated configuration, may take a while. Expect around 20-30 mins for the deployment, unless you have new hardware, and a bank of SSDs for storage!
|
||||
|
||||
Once the deployment has completed, you're ready to proceed with the lab.
|
||||
|
||||
## Update the Jenkins pipeline
|
||||
|
||||
In this task we will update the Jenkins pipeline to automatically deploy the artifacts after they have been built.
|
||||
|
||||
Navigate to the configuration of your pipeline:
|
||||
```
|
||||
http://ip_address_of_your_jenkinsmaster:8080/job/PartsUnlimitedMRP/configure
|
||||
```
|
||||
|
||||
In the pipeline, go to the end of the script (line 31) and **before the last line** (the trailing "}" you need to paste in the following code.
|
||||
|
||||
``` Groovy
|
||||
|
||||
stage ('Save MongoRecords.js') {
|
||||
dir('deploy') {
|
||||
archiveArtifacts artifacts: 'MongoRecords.js', excludes: '**/docker'
|
||||
}
|
||||
}
|
||||
|
||||
def mrpipaddress
|
||||
|
||||
stage ('Get MRP IP Address') {
|
||||
mrpipaddress = input(
|
||||
id: 'mrpipaddress', message: 'Please enter the MRP VM IP Address', parameters: [
|
||||
[$class: 'TextParameterDefinition', defaultValue: '192.168.102.1', description: 'This is the IP Address by which the VM can be remotely accessed', name: 'mrpipaddress']
|
||||
])
|
||||
echo ("MRP IP Address: ${mrpipaddress}")
|
||||
}
|
||||
|
||||
stage ("ssh") {
|
||||
sshagent(['mrpadmin']) {
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -O ${env.JENKINS_URL}/job/PartsUnlimitedMRP/lastSuccessfulBuild/artifact/build/libs/mrp.war'"
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -O ${env.JENKINS_URL}/job/PartsUnlimitedMRP/lastSuccessfulBuild/artifact/build/libs/integration-service-0.1.0.jar'"
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -O ${env.JENKINS_URL}/job/PartsUnlimitedMRP/lastSuccessfulBuild/artifact/build/libs/ordering-service-0.1.0.jar'"
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -O ${env.JENKINS_URL}/job/PartsUnlimitedMRP/lastSuccessfulBuild/artifact/MongoRecords.js'"
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -sL https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/docs/assets/jenkins/env/deploy_mrp_app.sh | sudo bash -'"
|
||||
}
|
||||
sh "curl -sL -w \"%{http_code}\\n\" http://${mrpipaddress}:9080/mrp/ -o /dev/null"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Click **Save**
|
||||
|
||||
**NOTE:** In the Azure Stack environment, because we have chosen not to automate the new build process on the changing of code in GitHub, you will still need to manually press **Build Now** in the Jenkins UI **After** we make a change to the code in GitHub.
|
||||
|
||||
The pipeline shall now be the following - **Make sure you change the git url on line 4, to your GitHub repository**.
|
||||
|
||||
``` Groovy
|
||||
|
||||
node{
|
||||
|
||||
stage ("Checkout") {
|
||||
git url: 'https://github.com/Microsoft/PartsUnlimitedMRP'
|
||||
}
|
||||
|
||||
env.JAVA_HOME = "${tool 'JDK 8'}"
|
||||
env.PATH = "${env.JAVA_HOME}/bin:${env.PATH}"
|
||||
sh 'java -version'
|
||||
|
||||
stage ('Build IntegrationService') {
|
||||
dir('src/Backend/IntegrationService') {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew build'
|
||||
archiveArtifacts artifacts: '**/integration-service*.jar', excludes: null
|
||||
}
|
||||
}
|
||||
|
||||
stage ('Build OrderService') {
|
||||
dir('src/Backend/OrderService') {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew build'
|
||||
archiveArtifacts artifacts: '**/ordering-service*.jar', excludes: null
|
||||
junit '**/TEST-*.xml'
|
||||
}
|
||||
}
|
||||
|
||||
stage ('Build Client') {
|
||||
dir('src/Clients') {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew build'
|
||||
archiveArtifacts artifacts: '**/mrp.war', excludes: null
|
||||
}
|
||||
}
|
||||
|
||||
stage ('Save MongoRecords.js') {
|
||||
dir('deploy') {
|
||||
archiveArtifacts artifacts: 'MongoRecords.js', excludes: '**/docker'
|
||||
}
|
||||
}
|
||||
|
||||
def mrpipaddress
|
||||
|
||||
stage ('Get MRP IP Address') {
|
||||
mrpipaddress = input(
|
||||
id: 'mrpipaddress', message: 'Please enter the MRP VM IP Address', parameters: [
|
||||
[$class: 'TextParameterDefinition', defaultValue: '192.168.102.1', description: 'This is the IP Address by which the VM can be remotely accessed', name: 'mrpipaddress']
|
||||
])
|
||||
echo ("MRP IP Address: ${mrpipaddress}")
|
||||
}
|
||||
|
||||
stage ("ssh") {
|
||||
sshagent(['mrpadmin']) {
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -O ${env.JENKINS_URL}/job/PartsUnlimitedMRP/lastSuccessfulBuild/artifact/build/libs/mrp.war'"
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -O ${env.JENKINS_URL}/job/PartsUnlimitedMRP/lastSuccessfulBuild/artifact/build/libs/integration-service-0.1.0.jar'"
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -O ${env.JENKINS_URL}/job/PartsUnlimitedMRP/lastSuccessfulBuild/artifact/build/libs/ordering-service-0.1.0.jar'"
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -O ${env.JENKINS_URL}/job/PartsUnlimitedMRP/lastSuccessfulBuild/artifact/MongoRecords.js'"
|
||||
sh "ssh -o StrictHostKeyChecking=no -l mrpadmin ${mrpipaddress} 'curl -sL https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/docs/assets/jenkins/env/deploy_mrp_app.sh | sudo bash -'"
|
||||
}
|
||||
sh "curl -sL -w \"%{http_code}\\n\" http://${mrpipaddress}:9080/mrp/ -o /dev/null"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Connecting the dots
|
||||
|
||||
**1.** Go to the source code on your GitHub repository
|
||||
|
||||
**2.** Edit the file **src/Clients/Web/index.html**
|
||||
|
||||
You can change the title of the page for example.
|
||||
|
||||
![Editing PartsUnlimitedMRP title](<../../../docs/assets/jenkins/edit_index.png>)
|
||||
|
||||
**3.** Click **Commit changes**
|
||||
|
||||
**4.** Navigate to your Jenkins master, and click **Build Now**
|
||||
```
|
||||
http://ip_address_of_your_jenkinsmaster:8080/job/PartsUnlimitedMRP/
|
||||
```
|
||||
|
||||
**5.** The build will begin, and the pipeline will stop at the stage **Get MRP IP Address**
|
||||
|
||||
Click on the step that is paused and enter the IP address of the MRP machine, this is the Parts Unlimited MRP with SSH VM you deployed earlier
|
||||
|
||||
Click **Proceed**
|
||||
|
||||
![Enter the IP Address of the deployment machine](/deploy/azurestack/docs/media/JenkinsGetMRPIP.PNG)
|
||||
|
||||
**6.** Wait until the completion of the pipeline
|
||||
|
||||
**7.** Navigate to the following address:
|
||||
|
||||
```
|
||||
http://ip_address_of_the_mrp_deployment_machine:9080/mrp
|
||||
```
|
||||
The IP address of the MRP deployment machine is the IP address of the Parts Unlimited MRP with SSH VM you deployed earlier
|
||||
|
||||
Verify that the Title in the browser is the same than the one you have modified in the code.
|
||||
|
||||
![Parts Unlimited Application](<../../../docs/assets/jenkins/pumrp_app.png>)
|
||||
|
||||
# Next steps
|
||||
|
||||
In this lab, you learned how to implement Continuous Deployment for the Parts Unlimited MRP Application.
|
||||
This allows you to reduce the time to go in production and get feedback if your changes are okay. Implemented with Continuous Integration, the changes performed by the developers are pushed, in a continuous manner into production without removing the ability to have human control.
|
||||
|
||||
If you're interested in learning more about DevOps tooling on Azure Stack, check out these Hands-On-Labs:
|
||||
|
||||
- [Continuous Deployment with Puppet](/deploy/azurestack/docs/puppet_setup.md)
|
||||
- [Continuous Deployment with Chef](/deploy/azurestack/docs/chef_setup.md)
|
||||
|
||||
# Continuous Feedback
|
||||
|
||||
#### Issues / Questions about this Hands-On-Lab ??
|
||||
|
||||
[If you are encountering issues or have questions during this Hands on Labs, please open an issue by clicking here](https://github.com/Microsoft/PartsUnlimitedMRP/issues)
|
||||
|
||||
Thanks
|
|
@ -0,0 +1,223 @@
|
|||
# Continuous Integration for Parts Unlimited MRP with Jenkins
|
||||
In this lab, we have an application called Parts Unlimited MRP. We want to set up Jenkins to be able continuously integrate code into the master branch of code. This means that whenever code is committed and pushed to the master branch, we want to ensure that it integrates into our code correctly to get fast feedback. To do so, we are going to be creating a pipeline that will allow us to compile and run unit tests on our code when it is pushed to GitHub.
|
||||
|
||||
## *Important Consideration for Azure Stack
|
||||
Combining Jenkins and GitHub allows for the automated building of an application as soon as developers check in code to their GitHub repository, through a capability known as webhooks. For instance, you can configure Jenkins and GitHub in such a way that when GitHub detects new code from your developers, it automatically sends information to Jenkins, which triggers the build process to start, using the freshly checked-in code. This is more efficient than having Jenkins poll GitHub on an interval for instance, or via manual triggering.
|
||||
|
||||
Due to the way that Azure Stack is configured from a networking perspective, utilizing webhooks from GitHub (resides on the public internet) and your Jenkins VM (inside an Azure Stack virtual network, which itself is likely inside your corporate network) is difficult. If you recall earlier, your IP address for your Jenkins Master VM is likely 192.168.102.X i.e. a private IP. This will not resolve on the public internet, and thus, GitHub would not be able to reach this address directly.
|
||||
|
||||
Workarounds include the use of a GitHub proxy, that has communication between the Jenkins VM and the public internet, or alternatively, configuring multiple NAT rules, using public IPs etc. to allow GitHub to reach the Jenkins Master VM. A more realistic alternative would be the deployment of GitHub Enterprise on-premises, which would provide GitHub functionlity, but within your corporate environment.
|
||||
|
||||
These workarounds are currently out of scope, but may be addressed in the future. For this lab, you will trigger builds manually in Jenkins.
|
||||
|
||||
## Pre-Requisites: ##
|
||||
|
||||
- Completion of the lab [Set up Parts Unlimited MRP with Jenkins](/deploy/azurestack/docs/jenkins_setup.md)
|
||||
- Have a GitHub account [https://github.com](https://github.com).
|
||||
|
||||
## Tasks Overview:
|
||||
During the following tasks you will fork the Parts Unlimited MRP github repository and create a Jenkins pipeline for the Continuous Integration of the Parts Unlimited MRP application. You will learn how to configure Jenkins so that whenever a change is checked in on the code repository, a build will be triggered and several tests will be performed.
|
||||
|
||||
### Configure your GitHub repository
|
||||
|
||||
**1.** Nagivate to [https://github.com/Microsoft/PartsUnlimitedMRP/](https://github.com/Microsoft/PartsUnlimitedMRP/)
|
||||
|
||||
**2.** Sign in with your github account
|
||||
|
||||
**3.** Click on Fork.
|
||||
|
||||
**NOTE**: if you have multiple accounts, select the account you want to fork to.
|
||||
|
||||
![Github fork](<../../../docs/assets/jenkins/github_fork.png>)
|
||||
|
||||
### Create a new pipeline
|
||||
In this task, we will create a new pipeline that will build the artifacts of the application. Before we do this however, there are a couple of settings to tweak on the Jenkins master, to ensure smooth operation of the lab.
|
||||
|
||||
**1.** Firstly navigate to:
|
||||
|
||||
```
|
||||
http://ip_address_of_your_jenkinsmaster:8080/configureSecurity/
|
||||
```
|
||||
|
||||
**2.** Check the box "Allow anonymous read access"
|
||||
|
||||
**3.** Untick the box "Prevent Cross Site Request Forgery exploits" and click **Save**
|
||||
|
||||
![CSRF_disabled](<../../../docs/assets/jenkins/csrf_disabled.png>)
|
||||
|
||||
This will Disable the CSRF protection on the Jenkins master but is an easy way to enable CI with Github.
|
||||
|
||||
Click **Save**
|
||||
|
||||
**4.** Create an empty pipeline: from your Jenkins master, click on **New Item**.
|
||||
|
||||
**NOTE:** You can also go directly to: http://IP_address_of_your_jenkinsmaster/view/All/newJob
|
||||
|
||||
![New Jenkins item](<../../../docs/assets/jenkins/jenkins_newitem.png>)
|
||||
|
||||
* Type the following name for the pipeline: **PartsUnlimitedMRP**
|
||||
* Select **Pipeline**
|
||||
* Click **OK**
|
||||
|
||||
![New Jenkins Pipeline](<../../../docs/assets/jenkins/jenkins_newpipeline.png>)
|
||||
|
||||
The pipeline type in Jenkins will allow us to describe all the build steps with Groovy code. This code can be easily ported on any Jenkins system and could also be embedded in a Jenkinsfile in the source code.
|
||||
|
||||
**5.** Create the Pipeline
|
||||
|
||||
Click on the tab name **Pipeline** and ensure that the definition is **Pipeline script**
|
||||
|
||||
The following code will clone the source code from PartsUnlimited, define the environment variables for the JDK and print the version of Java that we are using. Copy the script below in the **Script** box.
|
||||
|
||||
``` Groovy
|
||||
|
||||
node{
|
||||
stage ("Checkout") {
|
||||
git 'https://github.com/Microsoft/PartsUnlimitedMRP.git'
|
||||
}
|
||||
|
||||
env.JAVA_HOME = "${tool 'JDK 8'}"
|
||||
env.PATH = "${env.JAVA_HOME}/bin:${env.PATH}"
|
||||
sh 'java -version'
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Replace the git url with the url of your own github repository.
|
||||
|
||||
![Pipeline script](<../../../docs/assets/jenkins/pipeline_script1.png>)
|
||||
|
||||
The **stage** syntax in the code above defines a boundary of code that will be executed together. In a pipeline you can have as many stages as you want, they can run sequentially or in parallel, depending on the constraints that you have to build the application.
|
||||
|
||||
Click **Save** and then **Build Now**
|
||||
|
||||
![Pipeline script](<../../../docs/assets/jenkins/pipeline_build1.png>)
|
||||
|
||||
After few seconds you should have a successful build with following result:
|
||||
|
||||
![Build results](<../../../docs/assets/jenkins/build_result1.png>)
|
||||
|
||||
**6.** Building PartsUnlimitedMRP
|
||||
|
||||
Now that we have a basic pipeline, let's add the code that will define the build of the Parts Unlimited MRP application.
|
||||
The application is composed of three components:
|
||||
- The _Order Service_
|
||||
- The _Integration Service_
|
||||
- The _Client_ application
|
||||
|
||||
We will create a stage for each of those components.
|
||||
|
||||
Click on **Configure** on the left section.
|
||||
|
||||
Copy the following code in the pipeline script:
|
||||
|
||||
``` Groovy
|
||||
|
||||
node{
|
||||
stage ("Checkout") {
|
||||
git 'https://github.com/Microsoft/PartsUnlimitedMRP.git'
|
||||
}
|
||||
|
||||
env.JAVA_HOME = "${tool 'JDK 8'}"
|
||||
env.PATH = "${env.JAVA_HOME}/bin:${env.PATH}"
|
||||
sh 'java -version'
|
||||
|
||||
stage ("Integration Service") {
|
||||
dir('src/Backend/IntegrationService') {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew build'
|
||||
archiveArtifacts artifacts: '**/integration-service*.jar', excludes: null
|
||||
}
|
||||
}
|
||||
stage ("Order Service") {
|
||||
dir('src/Backend/OrderService') {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew build'
|
||||
archiveArtifacts artifacts: '**/ordering-service*.jar', excludes: null
|
||||
}
|
||||
}
|
||||
stage ("Clients") {
|
||||
dir('src/Clients') {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew build'
|
||||
archiveArtifacts artifacts: '**/mrp.war', excludes: null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Replace the git url with the url of your own github repository.
|
||||
|
||||
Click **Save** and then **Build Now**
|
||||
|
||||
**NOTE:** You may have to refresh the page once the build has completed to see the artifacts that have been produced.
|
||||
|
||||
![Build Pipeline for PartsUnlimitedMRP](<../../../docs/assets/jenkins/build_pipeline2.png>)
|
||||
|
||||
|
||||
### Adding test coverage
|
||||
The Parts Unlimited MRP Application performs tests for the OrderService component. In this task, we will add some information about the results of those tests and display the trend of the results of those tests.
|
||||
|
||||
**1.** Cick on **Configure** to edit your pipeline script.
|
||||
|
||||
**2.** After line 21, insert the following code
|
||||
```
|
||||
junit '**/TEST-*.xml'
|
||||
```
|
||||
|
||||
The new pipeline code is:
|
||||
|
||||
``` Groovy
|
||||
|
||||
node{
|
||||
stage ("Checkout") {
|
||||
git 'https://github.com/Microsoft/PartsUnlimitedMRP.git'
|
||||
}
|
||||
env.JAVA_HOME = "${tool 'JDK 8'}"
|
||||
env.PATH = "${env.JAVA_HOME}/bin:${env.PATH}"
|
||||
sh 'java -version'
|
||||
stage ("Integration Service") {
|
||||
dir('src/Backend/IntegrationService') {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew build'
|
||||
archiveArtifacts artifacts: '**/integration-service*.jar', excludes: null
|
||||
}
|
||||
}
|
||||
stage ("Order Service") {
|
||||
dir('src/Backend/OrderService') {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew build'
|
||||
archiveArtifacts artifacts: '**/ordering-service*.jar', excludes: null
|
||||
junit '**/TEST-*.xml'
|
||||
}
|
||||
}
|
||||
stage ("Clients") {
|
||||
dir('src/Clients') {
|
||||
sh 'chmod +x gradlew'
|
||||
sh './gradlew build'
|
||||
archiveArtifacts artifacts: '**/mrp.war', excludes: null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
**3.** Click on **Save** then **Build Now**, and once complete, click **Build Now** again.
|
||||
|
||||
The test results as displayed below will be displayed AFTER running two builds and refreshing the page.
|
||||
|
||||
![Pipeline with test results](<../../../docs/assets/jenkins/pipeline_withtest.png>)
|
||||
|
||||
|
||||
# Next steps
|
||||
|
||||
In this lab, you learned how to create a Continuous Integration build that runs when new commits are pushed to the master branch. This allows you to get feedback as to whether your changes made breaking syntax changes, or if they broke one or more automated tests, or if your changes are OK. Try this lab out for next steps:
|
||||
|
||||
- [Parts Unlimited MRP Continous Deployment with Jenkins](/deploy/azurestack/docs/jenkins_CD.md)
|
||||
|
||||
## Continuous Feedback
|
||||
|
||||
#### Issues / Questions about this Hands-On-Lab?
|
||||
|
||||
[If you are encountering issues or have questions during this Hands-on-Lab, please open an issue by clicking here](https://github.com/Microsoft/PartsUnlimitedMRP/issues)
|
|
@ -2,35 +2,255 @@
|
|||
In this multi-part lab, we will set up the Jenkins Master in Azure Stack, that will be used for the Parts Unlimited MRP project. We'll then step through using that environment to showcase CI/CD capabilities. [Jenkins](https://jenkins.io/) is an open source automation server that provides capabilities for building, deploying and automating any project.
|
||||
|
||||
## Prerequisites
|
||||
There are a couple of key things you'll need to have in place before setting up this lab environment, which, if you've been following the steps so far, you should already have them :-)
|
||||
There are a couple of key things you'll need to have in place before setting up this lab environment, which, if you've been following the steps so far, you should already have most of them :-)
|
||||
|
||||
- A configured Azure Stack, logged into MAS-CON01
|
||||
- The Azure Stack Tools downloaded to MAS-CON01 ([Details here](deploy/azurestack/docs/adding_vm_images.md))
|
||||
- An Ubuntu base image in the Platform Image Repository ([Details here](deploy/azurestack/docs/adding_vm_images.md))
|
||||
- The Azure Stack Tools downloaded to MAS-CON01 ([Details here](/deploy/azurestack/docs/adding_vm_images.md#connecting-to-azure-stack-via-powershell))
|
||||
- An Ubuntu base image in the Platform Image Repository ([Details here](/deploy/azurestack/docs/adding_vm_images.md#add-vm-image-to-platform-image-repository-with-powershell))
|
||||
- Putty installed on MAS-CON01 (use the script below, from an administrative PowerShell console to download)
|
||||
- An Oracle Account, in order to source the latest JDK (Test creds at http://www.oracle.com then click Sign-in at the top)
|
||||
|
||||
```powershell
|
||||
Invoke-Webrequest https://the.earth.li/~sgtatham/putty/latest/x86/putty.exe -OutFile C:\putty.exe
|
||||
```
|
||||
Once you've got all those sorted, you're ready to deploy the environment. The environment will consist of a single **resource group** containing 2 virtual machines, connected on a single virtual network. One of the virtual machines will be the **Jenkins Master**, while the other will be a standard Ubuntu Linux VM, that will be configured using Jenkins, later in the lab series.
|
||||
Once you've got all those sorted, you're ready to deploy the environment. The environment will consist of a single **resource group** containing the Jenkins Master VM, connected to a single virtual network. Later in the lab, you'll deploy another standard Ubuntu Linux VM, that will be configured using Jenkins.
|
||||
|
||||
## Deployment Options
|
||||
|
||||
Now, you have 2 options for deployment.
|
||||
|
||||
1. **ARM Template & Custom Deployment** -> for this option, you will perform a new custom template deployment from Azure Stack, using a JSON file that will be provided for you. You will enter a number of key values for the parameters, and then deploy. **This is the quicker option**.
|
||||
2. **Create a Custom Marketplace Item for Deployment** -> for this option, in the same way you added an Ubuntu 14.04-LTS item to the Azure Stack Marketplace, you will add a new .azpkg to your Azure Stack, and configure the deployment from this, providing the same parameters as per option 1.
|
||||
2. **Create a Custom Marketplace Item for Deployment** -> for this option, in the same way you (optionally) added an Ubuntu 16.04-LTS item to the Azure Stack Marketplace, you will add a new .azpkg to your Azure Stack, and configure the deployment from this, providing the same parameters as per option 1.
|
||||
|
||||
**The end result of both of these options is the same, however if you'd like to populate your gallery with more items, use option 2.
|
||||
**The end result of both of these options is the same, however if you'd like to populate your gallery with more items, use option 2.**
|
||||
|
||||
### *Option 1 - ARM Template & Custom Deployment
|
||||
<<<<<<< HEAD
|
||||
If you're not interested in creating a Marketplace item for 'Parts Unlimited MRP with Jenkins', then this quick and easy approach should make things, well, quick and easy for you!
|
||||
|
||||
Firstly, you need to click on the button below, and then enter some information:
|
||||
Firstly, from your MAS-CON01 machine, you need to click on the button below, and fill in the parameter fields. The link should open the Azure Stack portal, and if you're not already logged in, it'll prompt you for your Azure Stack credentials, then take you immediately to the custom template blade.
|
||||
|
||||
<a href="https://portal.azurestack.local/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FMicrosoft%2FPartsUnlimitedMRP%2Fmaster%2Fdeploy%2Fazurestack%2Finstances%2Fjenkins_mrp%2FPartsUnlimitedMRP.MRPwithJenkins%2FDeploymentTemplates%2FMRPwithJenkinsDeploy.json" target="_blank">
|
||||
<a href="https://adminportal.local.azurestack.external/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FMicrosoft%2FPartsUnlimitedMRP%2Fmaster%2Fdeploy%2Fazurestack%2Finstances%2Fjenkins_standalone%2FTheJenkinsProject.Jenkins%2FDeploymentTemplates%2FJenkinsDeploy.json" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/azurestack/docs/media/DeployToStack.png"/>
|
||||
</a>
|
||||
=======
|
||||
>>>>>>> 1dfa10603ffd4ccdc00834c74195be41f7f50f7c
|
||||
|
||||
You'll need to enter information for the following fields:
|
||||
- **JENKINSADMINPASSWORD** - choose a password of your choice.
|
||||
- **JENKINSDNSNAMEFORPUBLICIP** - for testing purposes, use **pumrp-jenkins**.
|
||||
- **Resource Group** - for testing purposes, use **pumrp-jenkins**.
|
||||
- **Location** - seeing as this is Azure Stack, you'll just be able to choose local in the current technical preview.
|
||||
|
||||
![Jenkins Deployment](/deploy/azurestack/docs/media/JenkinsDeploy.PNG)
|
||||
|
||||
If you're interested in taking a deeper look at the ARM template that is used for deployment, you could either **click Edit Template** within the custom template deployment blade, and that will present the template that will be used for the deployment, or alternatively, you could **[grab the ARM template from here](/deploy/azurestack/instances/jenkins_standalone/TheJenkinsProject.Jenkins/DeploymentTemplates/JenkinsDeploy.json)**
|
||||
|
||||
Depending on your hardware, the deployment of the key artifacts, the virtual machine, and its respective automated configuration, may take a while. Expect around 20-30 mins for the deployment, unless you have new hardware, and a bank of SSDs for storage!
|
||||
|
||||
Once the deployment has completed, you're ready to proceed with configuring Jenkins.
|
||||
|
||||
### *Option 2 - Create a Custom Marketplace Item for Deployment
|
||||
If you are interested in adding a custom marketplace item to your Azure Stack Marketplace, then these steps will help. I've already made the package for you, so you should just be able to follow these steps, and import it right into your Azure Stack.
|
||||
|
||||
As we saw earlier, when we [added our Ubuntu base image to the Azure Stack marketplace](/deploy/azurestack/docs/add_marketplace_item.md), things are much easier when something is packaged for you, so to start things off, pull down the .azpkg file for our Jenkins environment, that I've stored on GitHub. From yor **MAS-CON01** machine, do the following:
|
||||
|
||||
- [Download Jenkins Package](/deploy/azurestack/instances/jenkins_standalone/TheJenkinsProject.Jenkins.1.0.0.azpkg)
|
||||
|
||||
1. Navigate to your **TheJenkinsProject.Jenkins.1.0.0.azpkg** file, you downloaded earlier
|
||||
2. Move it to a newly created folder **C:\MyMarketPlaceItems**.
|
||||
|
||||
It’s important to note that if you are going to use the package I have provided, you need to have used the following info when you uploaded your Ubuntu base VHD image to the platform image repository [earlier](/deploy/azurestack/docs/adding_vm_images.md). Any differences, and the package I’m providing will not reference your uploaded image. If you used an exact copy of my PowerShell upload script, you're all set.
|
||||
|
||||
- Publisher "Canonical"
|
||||
- Offer "UbuntuServer"
|
||||
- SKU "16.04.3-LTS"
|
||||
|
||||
Now that we have the package ready to upload, we need *somewhere* in Azure Stack to upload it to. Fortunately, we [created a storage account for this very purpose earlier](/deploy/azurestack/docs/add_marketplace_item.md#uploading-a-package-to-azure-stack), so we'll use the same storage account for this package.
|
||||
|
||||
1. Connect to your Azure Stack via an **administrative PowerShell console**. If you're not still connected from the earlier steps, run the following:
|
||||
|
||||
``` powershell
|
||||
cd\
|
||||
cd C:\AzureStack-Tools-master\connect
|
||||
Import-Module .\AzureStack.Connect.psm1
|
||||
Add-AzureStackAzureRmEnvironment -Name "AzureStackAdmin" -ArmEndpoint "https://adminmanagement.local.azurestack.external"
|
||||
$TenantID = Get-DirectoryTenantID -AADTenantName "<myaadtenant>.onmicrosoft.com or customdomain.com" -EnvironmentName AzureStackAdmin
|
||||
$UserName='<username@myaadtenant.onmicrosoft.com or username@customdomain.com>'
|
||||
$Password='<administrator or user password>'| `
|
||||
ConvertTo-SecureString -Force -AsPlainText
|
||||
$Credential= New-Object PSCredential($UserName,$Password)
|
||||
Login-AzureRmAccount -EnvironmentName "AzureStackAdmin" -TenantId $TenantID -Credential $Credential
|
||||
```
|
||||
|
||||
2. Now, let's access the storage account to hold this package. If you recall, we named the storage account **tenantartifacts** and this is located in a dedicated **resource group** of the same name:
|
||||
|
||||
``` powershell
|
||||
$StorageAccount = Get-AzureRmStorageAccount -ResourceGroupName tenantartifacts -Name tenantartifacts
|
||||
$GalleryContainer = Get-AzureStorageContainer -Name gallery -Context $StorageAccount.Context
|
||||
```
|
||||
3. With the resource group, storage account and gallery container now accessible, we can push our new Jenkins marketplace package into Azure Stack.
|
||||
|
||||
``` powershell
|
||||
$GalleryContainer | Set-AzureStorageBlobContent -File "C:\MyMarketPlaceItems\TheJenkinsProject.Jenkins.1.0.0.azpkg"
|
||||
$GalleryItemURI = (Get-AzureStorageBlob -Context $StorageAccount.Context -Blob 'TheJenkinsProject.Jenkins.1.0.0.azpkg' -Container 'gallery').ICloudBlob.uri.AbsoluteUri
|
||||
Add-AzureRMGalleryItem -GalleryItemUri $GalleryItemURI -Verbose
|
||||
```
|
||||
|
||||
When successful, you should see a **StatusCode** of **Created**
|
||||
|
||||
![Successful Upload](/deploy/azurestack/docs/media/PSCreated.PNG)
|
||||
|
||||
Go back and refresh the portal, and under **New -> Virtual Machines -> See All**, you should see your newly added Jenkins marketplace item
|
||||
|
||||
![Jenkins added to Marketplace](/deploy/azurestack/docs/media/JenkinsMarketplace.PNG)
|
||||
|
||||
With your newly created marketplace item created and pushed to the Azure Stack Marketplace, we're ready to deploy an instance of the environment.
|
||||
|
||||
1. On the **MAS-CON01** machine, in your Azure Stack portal, click on **New**, then **Virtual Machines**, then **See all**.
|
||||
2. Select the **Jenkins** item in the marketplace, and click **Create**.
|
||||
3. Provide the information for the following fields:
|
||||
- **JENKINSADMINPASSWORD** - choose a password of your choice.
|
||||
- **JENKINSDNSNAMEFORPUBLICIP** - for testing purposes, use **pumrp-jenkins**.
|
||||
- **Resource Group** - for testing purposes, use **pumrp-jenkins**.
|
||||
- **Location** - seeing as this is Azure Stack, you'll just be able to choose local in the current technical preview.
|
||||
|
||||
Once you've filled in the fields, it should look like this:
|
||||
|
||||
![Deploying Jenkins](/deploy/azurestack/docs/media/JenkinsDeploy.PNG)
|
||||
|
||||
4. Click **OK** to confirm the parameters, and then **Create** to start the deployment.
|
||||
|
||||
Depending on your hardware, the deployment of the key artifacts, the virtual machine, and its respective automated configuration, may take a while. Expect around 20-30 mins for the deployment, unless you have new hardware, and a bank of SSDs for storage!
|
||||
Once the deployment has completed, you're ready to proceed with configuring Jenkins.
|
||||
|
||||
## Jenkins Setup
|
||||
Regardless of using Option 1, or Option 2, your environment should now be deployed. You can now continue with the configuration of the Jenkins environment specifically.
|
||||
|
||||
1. Firstly, we need to **obtain the public IP of the Jenkins Master VM**. In the Azure Stack portal, click on **Resource Groups** and look for the Resource Group that you have just created. Click on the virtual machine in the resource group (_pumrp-jenkins_ in this example) and look for the "Public IP address/DNS name label".
|
||||
|
||||
![Obtain the public IP of the Jenkins Master](/deploy/azurestack/docs/media/JenkinsMRPDeployed.PNG)
|
||||
|
||||
2. We can now **SSH to the Jenkins Master VM**. To do this, we'll use PuTTY, (or any other ssh tool that you like) to connect to the IP address of the VM, and once connected type the following information to login to the VM:
|
||||
|
||||
- login as: jenkinsadmin
|
||||
- password: your password chosen for **JENKINSADMINPASSWORD** at template deployment time
|
||||
|
||||
To make this lab easier, the user has been pre-configured to be **jenkinsadmin** through the automated deployment.
|
||||
|
||||
### Configure your Jenkins Master
|
||||
In this task, we will perform the basic configuration of the Jenkins master server and install the necessary plugins that will be used for Continuous Integration.
|
||||
|
||||
**1.** Obtain the initial admin password
|
||||
|
||||
From the SSH session that you have opened at the end of Task 1, type the following command to obtain the initial admin password.
|
||||
|
||||
``` bash
|
||||
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
|
||||
```
|
||||
|
||||
Copy the value returned by the command. Keep the SSH session open, we will return at the end of this task.
|
||||
|
||||
![Initial jenkins admin password](/deploy/azurestack/docs/media/JenkinsPassword.PNG)
|
||||
|
||||
**2.** Unlock the jenkins master
|
||||
|
||||
SOn MAS-CON01, with your browser, navigate to the default page of the Jenkins master.
|
||||
|
||||
```
|
||||
http://ip_address_of_your_jenkinsmaster:8080
|
||||
```
|
||||
|
||||
Paste the initial admin password obtained earlier to unlock your instance of Jenkins and click **Continue**.
|
||||
|
||||
![Initial jenkins admin password](/deploy/azurestack/docs/media/initial_jenkins_unlock.png)
|
||||
|
||||
Click **Install suggested plugins**
|
||||
|
||||
![Initial jenkins plugins](/deploy/azurestack/docs/media/initial_jenkins_plugins.png)
|
||||
|
||||
**3.** Create the first user
|
||||
|
||||
Create a user from the "Create First Admin User":
|
||||
* Username = Jenkins
|
||||
* Password = Passw0rd
|
||||
* Full name = Jenkins Admin
|
||||
* E-mail address = jenkins@microsoft.com
|
||||
* Click **Save and Finish**.
|
||||
|
||||
![Initial jenkins plugins](/deploy/azurestack/docs/media/JenkinsCreateAdminUser.PNG)
|
||||
|
||||
**4.** Start Using Jenkins
|
||||
|
||||
Click the **Start Using Jenkins** button to get started! You now have a virtual machine in Azure Stack running Jenkins as a Master. You should automatically be logged in as the user you have just created, but if not, logon to the Jenkins Master with the credentials that you have just created in step 4.
|
||||
|
||||
* Username = Jenkins
|
||||
* Password = Passw0rd
|
||||
|
||||
**5.** Navigate to the "Configure System" page:
|
||||
|
||||
From the left-hand navigation, click on **Manage Jenkins**, then **Configure System**
|
||||
|
||||
Under **Jenkins Location** look for the Jenkins URL field and type the URL of your Jenkins master: http://ip_address_of_your_jenkinsmaster:8080/
|
||||
|
||||
**NOTE:** the URL may already be here but type it again and save to ensure the proper completion of the rest of the lab.
|
||||
|
||||
![Jenkins URL](/deploy/azurestack/docs/media/JenkinsLocation.PNG)
|
||||
|
||||
Click **Save**
|
||||
|
||||
**6.** Install git
|
||||
|
||||
Switch to the SSH session that was opened during step 1.
|
||||
|
||||
Type the following command:
|
||||
```
|
||||
sudo apt-get install git -y
|
||||
```
|
||||
|
||||
### Configure Jenkins
|
||||
The three tools that we will need to create our pipeline on Jenkins needs to be configured on our instance of Jenkins.
|
||||
|
||||
Connect to the Jenkins master that you have configured in the previous task using port 8080:
|
||||
|
||||
```
|
||||
http://ip_address_of_your_jenkinsmaster:8080/manage
|
||||
```
|
||||
|
||||
**1.** Configure the JDK
|
||||
|
||||
From the Jenkins portal, on the left-hand navigation, click on **Manage Jenkins**, then **Global Tool Configuration**. In order to build the Parts Unlimited application we need to have the JDK installed.
|
||||
|
||||
Click on **Add JDK**
|
||||
|
||||
* Type the friendly name for the JDK: JDK 8
|
||||
* Ensure the box "Install automatically" is checked
|
||||
* In the drop-down list, select the latest version ("Java SE Development Kit 8u131" at the time of writing)
|
||||
* Check the box "I agree to the Java SE Development Kit License Agreement"
|
||||
* Click on the link to enter the username and password of your Oracle account (Test credentials here: https://www.oracle.com and click on Sign In at the top) then click **OK** then **Close**
|
||||
* Click **Save**
|
||||
|
||||
![JDK Installation](/deploy/azurestack/docs/media/JDKSettings.PNG)
|
||||
|
||||
**2.** Configure Gradle
|
||||
|
||||
Once you've been returned to the Manage Jenkins page, go to the **Global Tool Configuration** again.
|
||||
|
||||
Gradle will be used to build the Parts Unlimited MRP application. If needed, you could use Maven or Ant as well, the configuration would be very similar. Click on **Add Gradle**
|
||||
|
||||
* Type the friendly name for this installation of Gradle: "Gradle"
|
||||
* Verify that the "Install automatically" box is checked
|
||||
* Select the latest version of Gradle in the drop-down list.
|
||||
* Click **Save**
|
||||
|
||||
![Gradle Installation](/deploy/azurestack/docs/media/JenkinsGradle.PNG)
|
||||
|
||||
# Next steps
|
||||
|
||||
In this lab, you learned how to setup a Jenkins Master on Azure Stack, try these labs for the next steps:
|
||||
|
||||
- [Parts Unlimited MRP Continous Integration with Jenkins](/deploy/azurestack/docs/jenkins_CI.md)
|
||||
- [Parts Unlimited MRP Continous Deployment with Jenkins](/deploy/azurestack/docs/jenkins_CD.md)
|
||||
|
||||
## Continuous Feedback
|
||||
|
||||
#### Issues / Questions about this Hands-On-Lab?
|
||||
|
||||
[If you are encountering issues or have questions during this Hands on Labs, please open an issue by clicking here](https://github.com/Microsoft/PartsUnlimitedMRP/issues)
|
||||
|
|
После Ширина: | Высота: | Размер: 15 KiB |
После Ширина: | Высота: | Размер: 12 KiB |
После Ширина: | Высота: | Размер: 13 KiB |
После Ширина: | Высота: | Размер: 45 KiB |
После Ширина: | Высота: | Размер: 24 KiB |
После Ширина: | Высота: | Размер: 46 KiB |
После Ширина: | Высота: | Размер: 5.7 KiB |
После Ширина: | Высота: | Размер: 5.8 KiB |
После Ширина: | Высота: | Размер: 22 KiB |
После Ширина: | Высота: | Размер: 44 KiB |
После Ширина: | Высота: | Размер: 5.2 KiB |
После Ширина: | Высота: | Размер: 58 KiB |
После Ширина: | Высота: | Размер: 44 KiB |
После Ширина: | Высота: | Размер: 49 KiB |
После Ширина: | Высота: | Размер: 18 KiB |
После Ширина: | Высота: | Размер: 7.8 KiB |
После Ширина: | Высота: | Размер: 43 KiB |
После Ширина: | Высота: | Размер: 20 KiB |
После Ширина: | Высота: | Размер: 8.7 KiB |
После Ширина: | Высота: | Размер: 132 KiB |
После Ширина: | Высота: | Размер: 78 KiB |
После Ширина: | Высота: | Размер: 38 KiB |
После Ширина: | Высота: | Размер: 15 KiB |
После Ширина: | Высота: | Размер: 45 KiB |
После Ширина: | Высота: | Размер: 31 KiB |
После Ширина: | Высота: | Размер: 8.8 KiB |
После Ширина: | Высота: | Размер: 51 KiB |
После Ширина: | Высота: | Размер: 65 KiB |
После Ширина: | Высота: | Размер: 47 KiB |
После Ширина: | Высота: | Размер: 99 KiB |
После Ширина: | Высота: | Размер: 27 KiB |
Двоичные данные
deploy/azurestack/docs/media/UbuntuCreated.PNG
До Ширина: | Высота: | Размер: 21 KiB |
После Ширина: | Высота: | Размер: 40 KiB |
После Ширина: | Высота: | Размер: 7.5 KiB |
После Ширина: | Высота: | Размер: 66 KiB |
После Ширина: | Высота: | Размер: 45 KiB |
|
@ -0,0 +1,476 @@
|
|||
# Continuous Deployment with Puppet Enterprise
|
||||
|
||||
In this lab, you will learn how to deploy the Parts Unlimited MRP App in an automated fashion onto a Linux VM with Puppet Enterprise.
|
||||
After this lab, you will have a working continuous deployment environment in Puppet that will deploy the Parts Unlimited MRP app to a Virtual Machine in Azure Stack.
|
||||
|
||||
## Pre-Requisites:
|
||||
|
||||
- Completion of the lab [Setup Environment | Continuous Deployment with Puppet](/deploy/azurestack/docs/puppet_setup.md)
|
||||
|
||||
## Overview:
|
||||
During this lab, we will finalize configuration of Puppet Enterprise to manage the additional virtual machine that was also deployed in the previous lab, and once under management, deploy the Parts Unlimited MRP app in an automated fashion.
|
||||
|
||||
## Install Puppet Agent on the Node
|
||||
|
||||
First, we need to bring our previously deployed Ubuntu VM under the management of the Puppet Enterprise Master. To do that, you'll first need to log into the Puppet Enterprise Master.
|
||||
|
||||
If it's not already open, on MAS-CON01, open a browser and navigate to your Puppet Enterprise Master address. The _dnsaddress_ will be of the form _machinename_._local_.cloudapp.azurestack.external. Open a browser to https://_dnsaddress_. (Make sure you're going to http__s__, not http). If you followed the steps in the lab, your DNS address will be https://puppetmaster.local.cloudapp.azurestack.external.
|
||||
|
||||
You will be prompted about an invalid certificate - it is safe to ignore this for the purposes of this lab. If the Puppet configuration has succeeded, you should see the Puppet Console sign in page:
|
||||
|
||||
![Puppet Login](/deploy/azurestack/docs/media/PuppetLogin.png)
|
||||
|
||||
On the Puppet Enterprise sign-in screen, enter the username `admin` and the password you set during the deployment. When you log in, you should see a page like this:
|
||||
|
||||
![Puppet Logged in](/deploy/azurestack/docs/media/PuppetLoggedIn.png)
|
||||
|
||||
Now that we're successfully logged into the Puppet Enterprise Master, you are now ready to add the node to the Puppet Master. Once the node is added, the Puppet Master will be able to configure the node.
|
||||
|
||||
Before we do that however, we'll need to connect to our newly deployed **puppetnode1** machine, to ensure we can apply any specific commands to it. To get the info we need, perform the following:
|
||||
|
||||
1. Open the **Azure Stack Admin Portal** and navigate to **Resource Groups**
|
||||
|
||||
2. From there, click on your **puppet** resource group, then click on the **puppetnode1** virtual machine in the **Essentials** blade.
|
||||
|
||||
3. The details of **puppetnode1** should be displayed, and should look similar to these below:
|
||||
|
||||
![Puppet Node IP](/deploy/azurestack/docs/media/PuppetNodeDeployed.PNG)
|
||||
|
||||
4. Make a note of the IP and DNS name. If you've followed the steps, your DNS name should be puppetnode1.local.cloudapp.azurestack.external.
|
||||
|
||||
5. Fire up Putty, or a similar tool of your choice, and connect to the machine, either via IP, or DNS. Login with the credentials you specified when deploying the node.
|
||||
|
||||
Once you're all connected, you're ready to start connecting this node with the Puppet Enterprise Master.
|
||||
|
||||
1. Back in the Puppet Master console, go to Nodes -> Unsigned Certs. The page that loads will show a command that we need to run on the node. In the example below, the puppet master machine name is:
|
||||
|
||||
```
|
||||
puppetmaster.6786122c-04f9-4ccb-8ff4-21476954ec5f.internal.azurestack.local
|
||||
```
|
||||
![Puppet Unsigned Certs](/deploy/azurestack/docs/media/PuppetUnsignedCerts.png)
|
||||
|
||||
2. Copy the "Add Node" command from the Puppet Console (the one that starts with `curl...`), then switch back to your Putty session, and paste the code into the window, then run it. Note, if it appears that nothing is happening, you may need to press Enter after initially running the line of code, to trigger a sudo password prompt. From there, it should run to completion.
|
||||
|
||||
![Puppet Run Script](/deploy/azurestack/docs/media/PuppetAddNodePutty.PNG)
|
||||
|
||||
The command will take a few moments to complete. From here on, you will configure the node only from the Puppet Master, though you will use the Putty to manually force Puppet to configure it.
|
||||
|
||||
3. Return to the Puppet Console and refresh the Unsigned Certificates page (where you previously got the node install command). You should see a pending request. This request has come from the node and will authorize the certificate between the puppet master and the node so that they can communicate securely. Press "Accept" to approve the node:
|
||||
|
||||
![Accept Puppet Node](/deploy/azurestack/docs/media/PuppetAddNodeAccept.PNG)
|
||||
|
||||
Click on the "Nodes" tab in the Puppet Console to return to the nodes view. You should see 2 nodes listed:
|
||||
the puppet master and the new node (it may take a few minutes for the additional node to finish configuration before it appears)
|
||||
|
||||
![Accept Puppet Node](/deploy/azurestack/docs/media/PuppetNodeAdded.PNG)
|
||||
|
||||
## Configure the Puppet Production Environment
|
||||
|
||||
The Parts Unlimited MRP application is a Java application that requires [mongodb](https://www.mongodb.org/)
|
||||
and [tomcat](http://tomcat.apache.org/) to be installed and configured on the Parts Unlimited MRP machine (the node). Instead of
|
||||
installing and configuring manually, we will now write a puppet program that will instruct the node how to configure
|
||||
itself.
|
||||
|
||||
Puppet Programs are stored in a particular folder in the puppet master. Puppet programs are made up of manifests
|
||||
that describe the desired state of the node(s). The manifests can consume modules, which are pre-packaged Puppet
|
||||
Programs. Users can create their own modules or consume modules from a marketplace maintained by PuppetLabs known
|
||||
as the [Forge](http://forge.puppetlabs.com). Some modules on the Forge are official modules that are supported -
|
||||
others are open-source modules uploaded from the community.
|
||||
|
||||
Puppet Programs are organized by environment, allowing you to manage different catalogs for different environments such as dev, test and production.
|
||||
|
||||
For the purposes of this lab, we will treat the node as if it were in the production environment. We will also need to
|
||||
download a few modules from the Forge which we will consume to configure the node.
|
||||
|
||||
When the Puppet Server was installed in Azure Stack, it configured a folder for managing the production environment
|
||||
in `/etc/puppetlabs/code/environments/production`.
|
||||
|
||||
1. The first thing we need to do is inspect the Production modules. To do so, we'll establish a Putty SSH session to the Puppet Master, which if you recall, should be **puppetmaster.local.cloudapp.azurestack.external** assuming you followed the steps exactly. Once connected, cd to that folder now:
|
||||
|
||||
```sh
|
||||
cd /etc/puppetlabs/code/environments/production
|
||||
```
|
||||
|
||||
If you run `ls` you will see the `manifests` and `modules` folders. The `manifests` folder contains descriptions
|
||||
of machines that we will later apply to nodes. The `modules` folder contains any modules that are referenced
|
||||
within the manifests.
|
||||
|
||||
2. We will now install some modules from the Puppet Forge that we will need to configure the `partsmrp` node. Run the following 3 commands:
|
||||
|
||||
```sh
|
||||
sudo puppet module install puppetlabs-mongodb
|
||||
sudo puppet module install puppetlabs-tomcat
|
||||
sudo puppet module install maestrodev-wget
|
||||
```
|
||||
|
||||
![Add Modules](/deploy/azurestack/docs/media/PuppetInstallModules.PNG)
|
||||
|
||||
>**Note:** The `mongodb` and `tomcat` modules are supported modules from the Forge. The `wget` module is
|
||||
a user module and so is not officially supported.
|
||||
|
||||
3. We will now create a custom module that will configure the Parts Unlimited MRP app. Run the following commands to template a module:
|
||||
|
||||
```sh
|
||||
cd modules/
|
||||
sudo puppet module generate partsunlimited-mrpapp
|
||||
```
|
||||
|
||||
This will start a wizard that will ask a series of questions as it scaffolds the module. Simply press `enter`
|
||||
for each question (accepting blank or default) until the wizard completes.
|
||||
|
||||
Running `ls -la` should list the modules available so far, including `mrpapp`:
|
||||
|
||||
![Added Module](/deploy/azurestack/docs/media/PuppetLSLa.PNG)
|
||||
|
||||
1. We are going to define the node's configuration in the `mrpapp` module. The configuration of the nodes in the production environment is defined in a `site.pp` file in the production `manifests` folder (the `.pp` extension is short for "puppet program"). Let's edit the `site.pp` file and define the configuration for our node:
|
||||
|
||||
```sh
|
||||
sudo nano /etc/puppetlabs/code/environments/production/manifests/site.pp
|
||||
```
|
||||
|
||||
Scroll to the bottom of the file and edit the `node default` section. Edit it to look as follows:
|
||||
|
||||
```puppet
|
||||
node default {
|
||||
class { 'mrpapp': }
|
||||
}
|
||||
```
|
||||
|
||||
Press `ctrl-X`, then `y` then `enter` to save the changes to the file.
|
||||
|
||||
This instructs Puppet to configure the `default` (that is, all nodes) with the `mrpapp` module. The module (though
|
||||
currently empty) is in the `modules` folder of the production environment, so Puppet will know where to find
|
||||
it.
|
||||
|
||||
## Test the Production Environment Configuration
|
||||
|
||||
Before we fully describe the MRP app for the node, let's test that everything is hooked up correctly by
|
||||
configuring a "dummy" file in the `mrpapp` module. If Puppet executes and creates the dummy file, then we can
|
||||
flesh out the rest of the module properly.
|
||||
|
||||
1. Let's edit the `init.pp` file of the `mrpapp` module (this is the entry point for the module):
|
||||
|
||||
```sh
|
||||
sudo nano /etc/puppetlabs/code/environments/production/modules/mrpapp/manifests/init.pp
|
||||
```
|
||||
|
||||
You can either delete all the boiler-plate comments or just ignore them. Scroll down to the `class mrpapp`
|
||||
declaration and make it look as follows:
|
||||
|
||||
```puppet
|
||||
class mrpapp {
|
||||
file { '/tmp/dummy.txt':
|
||||
ensure => 'present',
|
||||
content => 'Puppet rules!',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Press `ctrl-X`, then `y` then `enter` to save the changes to the file.
|
||||
|
||||
>**Note:** Classes in Puppet programs are not like classes in Object Oriented Programming. They simply define
|
||||
a "resource" that is configured on a node. In the `mrpapp` class (or resource), we have just instructed
|
||||
Puppet to ensure that a file exists at the path `/tmp/dummy.txt` that has the content "Puppet rules!". We
|
||||
will define more advanced resources within the `mrpapp` class as we progress.
|
||||
|
||||
1. Now, let's test our setup. Switch to the `puppetnode1` Putty terminal and enter the following command:
|
||||
|
||||
```sh
|
||||
sudo puppet agent --test
|
||||
```
|
||||
|
||||
By default, the Puppet agents will query the Puppet Master for their configuration every 30 minutes. The
|
||||
command you just entered forces the agent to ask the Puppet Master for its configuration. It then tests
|
||||
itself against the configuration, and does whatever it needs to do in order to make itself match that
|
||||
configuration. In this case, the configuration requires the `/tmp/dummy.txt` file, so the node creates
|
||||
the file accordingly.
|
||||
|
||||
You should see a successful run on the node. `cat` the `/tmp/dummy.txt` file to inspect its contents:
|
||||
|
||||
```sh
|
||||
cat /tmp/dummy.txt
|
||||
```
|
||||
|
||||
![Added Dummy Text File](/deploy/azurestack/docs/media/PuppetRules.PNG)
|
||||
|
||||
2. Puppet will automatically detect configuration drift and fix it. By default, the agent runs every 30 minutes on the nodes. Each time the agent runs, Puppet will determine if the environment is in the correct state - if it is not, it will reapply classes as necessary.
|
||||
|
||||
Let's simulate configuration drift by deleting the dummy file and then re-running the puppet agent:
|
||||
|
||||
```sh
|
||||
sudo rm /tmp/dummy.txt
|
||||
cat /tmp/dummy.txt
|
||||
sudo puppet agent --test
|
||||
cat /tmp/dummy.txt
|
||||
```
|
||||
|
||||
You should see the run complete successfully and the file should exist again.
|
||||
|
||||
![Added Dummy Text File](/deploy/azurestack/docs/media/PuppetRules2.PNG)
|
||||
|
||||
You can also try to edit the contents of the file and re-run the `sudo puppet agent --test` command to see the
|
||||
contents update.
|
||||
|
||||
## Create a Puppet Program to Describe the Prerequisites for the MRP Application
|
||||
|
||||
Now that we have hooked up the node (partsmrp) to the Puppet Master, we can begin to write the Puppet Program
|
||||
that will describe the prerequisites for the Parts Unlimited MRP application.
|
||||
|
||||
>**Note:** For simplicity, we will describe the entire configuration in a single Puppet Program (init.pp from
|
||||
the mrpapp module we created earlier). However, the parts of the configuration could be split into multiple
|
||||
manifests or modules as they grow. This would promote reuse - just as in any good programming language.
|
||||
|
||||
>**Note:** You can see the complete `init.pp` file [here](https://github.com/Microsoft/PartsUnlimitedMRP/blob/master/docs/HOL_Deploying-Using-Puppet/final/init.pp).
|
||||
|
||||
### Configure MongoDb
|
||||
|
||||
Let's add a class to configure mongodb. Once mongodb is configured, we want Puppet to download a mongo script that contains some data for our application's database. We'll include this as part of the mongodb setup.
|
||||
|
||||
On the Puppet Master, edit the init.pp file of the mrpapp module:
|
||||
```sh
|
||||
sudo nano /etc/puppetlabs/code/environments/production/modules/mrpapp/manifests/init.pp
|
||||
```
|
||||
|
||||
Add the following class at the bottom of the file:
|
||||
|
||||
```puppet
|
||||
class configuremongodb {
|
||||
include wget
|
||||
class { 'mongodb': }->
|
||||
|
||||
wget::fetch { 'mongorecords':
|
||||
source => 'https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/MongoRecords.js',
|
||||
destination => '/tmp/MongoRecords.js',
|
||||
timeout => 0,
|
||||
}->
|
||||
exec { 'insertrecords':
|
||||
command => 'mongo ordering /tmp/MongoRecords.js',
|
||||
path => '/usr/bin:/usr/sbin',
|
||||
unless => 'test -f /tmp/initcomplete'
|
||||
}->
|
||||
file { '/tmp/initcomplete':
|
||||
ensure => 'present',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Let's examine this class:
|
||||
- Line 1: We create a class (resource) called `configuremongodb`
|
||||
- Line 2: We include the `wget` [module](https://forge.puppetlabs.com/maestrodev/wget) so that we can
|
||||
download files via `wget`
|
||||
- Line 3: We invoke the `mondodb` resource (from the `mongodb` module we downloaded earlier). This installs
|
||||
mongodb using defaults defined in the [Puppet mongodb module](https://forge.puppetlabs.com/puppetlabs/mongodb).
|
||||
Believe it or not, that's all we have to do to install mondodb!
|
||||
- Line 5: We invoke the `fetch` resource from the `wget` module, calling this resource `mongorecords`
|
||||
- Line 6: We set the source of the file we need to download
|
||||
- Line 7: We set the destination where the file must be downloaded to
|
||||
- Line 10: We use the built-in Puppet resource `exec` to execute a command
|
||||
- Line 11: We specify the command to execute
|
||||
- Line 12: We set the path for the command invocation
|
||||
- Line 13: We specify a condition using the keyword `unless`: we only want this command to execute once, so we
|
||||
create a tmp file once we have inserted the records (Line 15). If this file exists, we don't execute the
|
||||
command again.
|
||||
|
||||
>**Note**: The `->` notation on Lines 3, 9 and 14 is an "ordering arrow": it tells Puppet that it must apply the
|
||||
"left" resource before invoking the "right" resource. This allows us to specify order when necessary.
|
||||
|
||||
Press `ctrl-O`, then `enter` to save the changes to the file without exiting.
|
||||
|
||||
### Configure Java
|
||||
|
||||
Add the following class below the `configuremongodb` class:
|
||||
|
||||
```puppet
|
||||
class configurejava {
|
||||
include apt
|
||||
$packages = ['openjdk-8-jdk', 'openjdk-8-jre']
|
||||
|
||||
apt::ppa { 'ppa:openjdk-r/ppa': }->
|
||||
package { $packages:
|
||||
ensure => 'installed',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Let's examine this class:
|
||||
- Line 2: We include the `apt` module, which will allow us to configure new Personal Package Archives (PPAs)
|
||||
- Line 3: We create an array of packages that we need to install
|
||||
- Line 5: We add a PPA
|
||||
- Lines 6 - 8: We tell Puppet to ensure that the package are installed. Puppet expands the array and essentially does a for-each, installing each package in the array.
|
||||
|
||||
>**Note:** We can't use the Puppet `package` target to install Java since this will only install Java 7. That's
|
||||
why we needed to add the PPA using the `apt` module.
|
||||
|
||||
Press `ctrl-O`, then `enter` to save the changes to the file without exiting.
|
||||
|
||||
### Configure Tomcat
|
||||
|
||||
Let's add a class below the `configurejava` class to configure `tomcat`:
|
||||
|
||||
```puppet
|
||||
class configuretomcat {
|
||||
class { 'tomcat': }
|
||||
|
||||
tomcat::instance { 'default':
|
||||
package_name => 'tomcat7',
|
||||
install_from_source => false,
|
||||
}->
|
||||
tomcat::config::server::connector { 'tomcat7-http':
|
||||
catalina_base => '/var/lib/tomcat7',
|
||||
port => '9080',
|
||||
protocol => 'HTTP/1.1',
|
||||
connector_ensure => 'present',
|
||||
server_config => '/etc/tomcat7/server.xml',
|
||||
}->
|
||||
tomcat::service { 'default':
|
||||
use_jsvc => false,
|
||||
use_init => true,
|
||||
service_name => 'tomcat7',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Let's examine this class:
|
||||
- Line 1: We create a class (resource) called `configuretomcat`
|
||||
- Line 2: We invoke the `tomcat` resource (from the [tomcat module](https://forge.puppetlabs.com/puppetlabs/mongodb) we downloaded earlier)
|
||||
- Line 4: We need to override some default properties for the tomcat instance. We specify the tomcat package we need (Line 5) and tell the `tomcat` class not to install from source (Line 6).
|
||||
- Lines 8 - 14: We configure the Tomcat service
|
||||
- Lines 15 - 19: We need to configure a connector for the Parts Unlimited MRP application. In Lines 9 - 13, we specify the connector properties for Puppet to write to the tomcat server.xml file.
|
||||
|
||||
Press `ctrl-O`, then `enter` to save the changes to the file without exiting.
|
||||
|
||||
### Deploy a WAR File
|
||||
|
||||
The MRP application is compiled into a WAR file that Tomcat then uses to serve pages.
|
||||
|
||||
Let's specify a resource to deploy the war file for the site. Go back to the Puppet SSH session and edit the `init.pp` file.
|
||||
Add the following class at the bottom of the file:
|
||||
|
||||
```puppet
|
||||
class deploywar {
|
||||
require configuretomcat
|
||||
|
||||
tomcat::war { 'mrp.war':
|
||||
catalina_base => '/var/lib/tomcat7',
|
||||
war_source => 'https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/builds/mrp.war',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Press `ctrl-O`, then `enter` to save the changes to the file without exiting.
|
||||
|
||||
Let's examine this class:
|
||||
- Line 1: We create a class (resource) called `deploywar`
|
||||
- Line 2: We tell Puppet to make sure that `configuretomcat` is complete before invoking this class
|
||||
- Line 5: We set the `catalina base` directory so that Puppet deploys the war to our Tomcat service
|
||||
- Line 6: We use the tomcat module's `war` resource to deploy our war from the `war_source`
|
||||
|
||||
### Start the Ordering Service
|
||||
|
||||
The MRP service calls an Ordering Service, which is a REST API managing orders in the MongoDb. This service is compiled to a
|
||||
jar file. We'll need to copy the jar file to our node and then run it in the background so that it can listen for requests.
|
||||
|
||||
Now we need to make sure that the ordering service is running. Again we'll add a new class at the bottom of the `init.pp` file:
|
||||
|
||||
```puppet
|
||||
class orderingservice {
|
||||
|
||||
file { '/opt/mrp':
|
||||
ensure => 'directory'
|
||||
}->
|
||||
wget::fetch { 'orderingsvc':
|
||||
source => 'https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/builds/ordering-service-0.1.0.jar',
|
||||
destination => '/opt/mrp/ordering-service.jar',
|
||||
cache_dir => '/var/cache/wget',
|
||||
timeout => 0,
|
||||
}->
|
||||
exec { 'stoporderingservice':
|
||||
command => "pkill -f ordering-service",
|
||||
path => '/bin:/usr/bin:/usr/sbin',
|
||||
onlyif => "pgrep -f ordering-service"
|
||||
}->
|
||||
exec { 'stoptomcat':
|
||||
command => 'service tomcat7 stop',
|
||||
path => '/bin:/usr/bin:/usr/sbin',
|
||||
onlyif => 'service tomcat7 status',
|
||||
}->
|
||||
exec { 'orderservice':
|
||||
command => 'java -jar /opt/mrp/ordering-service.jar &',
|
||||
path => '/usr/bin:/usr/sbin:/usr/lib/jvm/java-8-openjdk-amd64/bin',
|
||||
}->
|
||||
exec { 'wait':
|
||||
command => 'sleep 20',
|
||||
path => '/bin',
|
||||
notify => Tomcat::Service['default']
|
||||
}
|
||||
}
|
||||
```
|
||||
Press `ctrl-O`, then `enter` to save the changes to the file without exiting.
|
||||
|
||||
Let's examine this class:
|
||||
- Line 1: We create a class (resource) called `orderingservice`
|
||||
- Lines 2 - 4: We install the Java JRE required to run the application using Puppet's `package` resource
|
||||
- Lines 6 - 8: We ensure that the directory `/opt/mrp` exists (Puppet creates it if it doesnt)
|
||||
- Lines 9 - 14: We `wget` the ordering service binary, placing it in `/opt/mrp`
|
||||
- Line 12: We specify a cache directory to ensure that the file is only downloaded once
|
||||
- Lines 15 - 19: We stop the `orderingservice`, but only if it is running
|
||||
- Lines 20 - 24: We stop the `tomcat7` service, but only if it is running
|
||||
- Lines 25 - 28: We start the ordering service
|
||||
- Lines 29 - 33: We sleep for 20 seconds to give the ordering service time to start up before `notifying` the `tomcat` service, which triggers a refresh on the service - Puppet will re-apply the state we defined for the service (i.e. start it if it is not running)
|
||||
|
||||
>**Note:** We need to wait after running the `java` command since this service needs to be running before we start Tomcat, otherwise Tomcat grabs the port that the ordering service needs to listen on.
|
||||
|
||||
### Complete the mrpapp Resource
|
||||
|
||||
Go back to the top of the file and change the `mrpapp` class to look as follows to run all our resources:
|
||||
|
||||
```puppet
|
||||
class mrpapp {
|
||||
class { 'configuremongodb': }
|
||||
class { 'configurejava': }
|
||||
class { 'configuretomcat': }
|
||||
class { 'deploywar': }
|
||||
class { 'orderingservice': }
|
||||
}
|
||||
```
|
||||
|
||||
Press `ctrl-O`, then `enter` to save the changes to the file without exiting.
|
||||
|
||||
## Run the Puppet Configuration on the Node
|
||||
|
||||
1. On the partsmrp SSH session, again force Puppet to update the node's configuration:
|
||||
```sh
|
||||
sudo puppet agent --test
|
||||
```
|
||||
|
||||
This first run will take a few moments - there is lots to download and install for the first run! Next time the Puppet agent runs,
|
||||
it will verify that the existing environment is correctly configured - that should be much quicker since the services will already
|
||||
be installed and configured.
|
||||
|
||||
2. We need to check if Tomcat is running, so open a browser and browse to port `9080` of the partsmrp machine. You can get the name of the machine by clicking on the Public IP. If you've followed the steps exactly, it should be puppetnode1.local.cloudapp.azurestack.external. You can check in the Azure Stack portal (just like you did to get the url of the puppet master earlier). Once you open the browser, you should see the following Tomcat confirmation page:
|
||||
|
||||
![Tomcat Running](/deploy/azurestack/docs/media/PuppetTomcat.PNG)
|
||||
|
||||
3. Now you can ensure that the configuration is correct by opening a browser to the Parts Unlimited MRP application. The address
|
||||
will be http://puppetnode1.local.cloudapp.azurestack.external:9080/mrp, assuming you used puppetnode1 as your chosen VM name.
|
||||
|
||||
![Tomcat Running](/deploy/azurestack/docs/media/PuppetPartsMRPRunning.PNG)
|
||||
|
||||
In this lab, you learned how to create the Puppet infrastructure and deploy the Parts Unlimited MRP app to the nodes while managing configuration drift.
|
||||
|
||||
# Next steps
|
||||
|
||||
In this lab, you learned how to create the Puppet infrastructure and deploy the Parts Unlimited MRP app to the nodes while managing configuration drift. You can follow the steps again to deploy additional nodes under management. Each Puppet Enterprise deployment allows you to manage up to 10 nodes for free - great for learning and development!
|
||||
|
||||
If you're interested in learning more about DevOps tooling on Azure Stack, check out these Hands-On-Labs:
|
||||
|
||||
- [Continuous Deployment with Jenkins](/deploy/azurestack/docs/jenkins_setup.md)
|
||||
- [Continuous Deployment with Chef](/deploy/azurestack/docs/chef_setup.md)
|
||||
|
||||
# Continuous Feedback
|
||||
|
||||
#### Issues / Questions about this Hands-On-Lab ??
|
||||
|
||||
[If you are encountering issues or have questions during this Hands on Labs, please open an issue by clicking here](https://github.com/Microsoft/PartsUnlimitedMRP/issues)
|
||||
|
||||
Thanks
|
|
@ -1 +1,193 @@
|
|||
# Setup Environment | Continuous Deployment with Puppet
|
||||
|
||||
In this multi-part lab, we will set up the Puppet Master in Azure Stack, that will be used for Continuous Deployment of the Parts Unlimited MRP project. We'll then step through using that environment to showcase its CD capabilities. [Puppet](https://puppetlabs.com/) is a configuration management system that allows you to automate provisioning and configuration of machines by describing the state of your infrastructure as code. Infrastructure as Code is an important pillar of good DevOps.
|
||||
|
||||
## Prerequisites
|
||||
There are a couple of key things you'll need to have in place before setting up this lab environment, which, if you've been following the steps across other labs so far, you should already have most of them :-)
|
||||
|
||||
- A configured Azure Stack, logged into MAS-CON01
|
||||
- The Azure Stack Tools downloaded to MAS-CON01 ([Details here](/deploy/azurestack/docs/adding_vm_images.md#connecting-to-azure-stack-via-powershell))
|
||||
- An Ubuntu base image in the Platform Image Repository ([Details here](/deploy/azurestack/docs/adding_vm_images.md#add-vm-image-to-platform-image-repository-with-powershell))
|
||||
- Putty installed on MAS-CON01 (use the script below, from an administrative PowerShell console to download)
|
||||
|
||||
```powershell
|
||||
Invoke-Webrequest https://the.earth.li/~sgtatham/putty/latest/x86/putty.exe -OutFile C:\putty.exe
|
||||
```
|
||||
|
||||
Once you've got all those sorted, you're ready to deploy the environment. In this lab you will work with two machines: a Puppet Master machine and another machine known as a node which will host the MRP application. The only task you will perform on the node is to install the Puppet agent - the rest of the configuration will be applied by instructing Puppet how to configure the node though puppet programs on the Puppet Master. Specifically, you'll perform:
|
||||
|
||||
- Provisioning a Puppet Master and node (both Ubuntu VMs) in Azure Stack using ARM templates
|
||||
- Install Puppet Agent on the node
|
||||
- Configure the Puppet Environment
|
||||
- Test the Environment Configuration
|
||||
- Create a Puppet program to describe the environment for the MRP application
|
||||
|
||||
## Provisioning the Puppet Enterprise Master | Deployment Options
|
||||
|
||||
Now, you have 2 options for deployment.
|
||||
|
||||
1. **ARM Template & Custom Deployment** -> for this option, you will perform a new custom template deployment from Azure Stack, using a JSON file that will be provided for you. You will enter a number of key values for the parameters, and then deploy. **This is the quicker option**.
|
||||
2. **Create a Custom Marketplace Item for Deployment** -> for this option, in the same way you (optionally) added an Ubuntu 16.04-LTS item to the Azure Stack Marketplace, you will add a new .azpkg to your Azure Stack, and configure the deployment from this, providing the same parameters as per option 1.
|
||||
|
||||
**The end result of both of these options is the same, however if you'd like to populate your gallery with more items, use option 2.**
|
||||
|
||||
### *Option 1 - ARM Template & Custom Deployment
|
||||
If you're not interested in creating a Marketplace item for Puppet, then this quick and easy approach should make things, well, quick and easy for you!
|
||||
|
||||
Firstly, from your MAS-CON01 machine, you need to click on the button below, and fill in the parameter fields. The link should open the Azure Stack portal, and if you're not already logged in, it'll prompt you for your Azure Stack credentials, then take you immediately to the custom template blade.
|
||||
|
||||
<a href="https://adminportal.local.azurestack.external/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FMicrosoft%2FPartsUnlimitedMRP%2Fmaster%2Fdeploy%2Fazurestack%2Finstances%2Fpuppet_standalone%2FPuppet.PuppetEnterprise%2FDeploymentTemplates%2FPuppetDeploy.json" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/azurestack/docs/media/DeployToStack.png"/>
|
||||
</a>
|
||||
|
||||
You'll need to enter information for the following fields:
|
||||
|
||||
- **PMADMINPASSWORD** - choose a password of your choice.
|
||||
- **PMDNSNAMEFORPUBLICIP** - for testing purposes, use **puppetmaster**.
|
||||
- **PMCONSOLEPASSWORD** - choose a password of your choice.
|
||||
- **Resource Group** - for testing purposes, use **puppet**.
|
||||
- **Location** - seeing as this is Azure Stack, you'll just be able to choose local in the current technical preview.
|
||||
|
||||
![Puppet Deployment](/deploy/azurestack/docs/media/PuppetDeploy.png)
|
||||
|
||||
If you're interested in taking a deeper look at the ARM template that is used for deployment, you could either **click Edit Template** within the custom template deployment blade, and that will present the template that will be used for the deployment, or alternatively, you could **[grab the ARM template from here](/deploy/azurestack/instances/puppet_standalone/Puppet.PuppetEnterprise/DeploymentTemplates/PuppetDeploy.json)**
|
||||
|
||||
Depending on your hardware, the deployment of the key artifacts, the virtual machine, and its respective automated configuration, may take a while. Expect around 20-30 mins for the deployment, unless you have new hardware, and a bank of SSDs for storage!
|
||||
|
||||
Once the deployment has completed, you're ready to proceed with configuring the Puppet Master.
|
||||
|
||||
### *Option 2 - Create a Custom Marketplace Item for Deployment
|
||||
If you are interested in adding a custom marketplace item for Puppet Enterprise, to your Azure Stack Marketplace, then these steps will help. I've already made the package for you, so you should just be able to follow these steps, and import it right into your Azure Stack.
|
||||
|
||||
As we saw earlier, when we [added our Ubuntu base image to the Azure Stack marketplace](/deploy/azurestack/docs/add_marketplace_item.md), things are much easier when something is packaged for you, so to start things off, pull down the .azpkg file for our Puppet environment, that I've stored on GitHub. From yor **MAS-CON01** machine, do the following:
|
||||
|
||||
- [Download Puppet Enterprise Package](https://github.com/Microsoft/PartsUnlimitedMRP/raw/master/deploy/azurestack/instances/puppet_standalone/Puppet.PuppetEnterprise.1.0.0.azpkg)
|
||||
|
||||
1. Navigate to your **Puppet.PuppetEnterprise.1.0.0.azpkg** file, you downloaded earlier
|
||||
2. Move it to a newly created folder **C:\MyMarketPlaceItems**.
|
||||
|
||||
It’s important to note that if you are going to use the package I have provided, you need to have used the following info when you uploaded your Ubuntu base VHD image to the platform image repository [earlier](/deploy/azurestack/docs/adding_vm_images.md). Any differences, and the package I’m providing will not reference your uploaded image. If you used an exact copy of my PowerShell upload script, you're all set.
|
||||
|
||||
- Publisher "Canonical"
|
||||
- Offer "UbuntuServer"
|
||||
- SKU "16.04.3-LTS"
|
||||
|
||||
Now that we have the package ready to upload, we need *somewhere* in Azure Stack to upload it to. Fortunately, we [created a storage account for this very purpose earlier](/deploy/azurestack/docs/add_marketplace_item.md#uploading-a-package-to-azure-stack), so we'll use the same storage account for this package.
|
||||
|
||||
1. Connect to your Azure Stack via an **administrative PowerShell console**. If you're not still connected from the earlier steps, run the following:
|
||||
|
||||
``` powershell
|
||||
cd\
|
||||
cd C:\AzureStack-Tools-master\connect
|
||||
Import-Module .\AzureStack.Connect.psm1
|
||||
Add-AzureStackAzureRmEnvironment -Name "AzureStackAdmin" -ArmEndpoint "https://adminmanagement.local.azurestack.external"
|
||||
$TenantID = Get-DirectoryTenantID -AADTenantName "<myaadtenant>.onmicrosoft.com or customdomain.com" -EnvironmentName AzureStackAdmin
|
||||
$UserName='<username@myaadtenant.onmicrosoft.com or username@customdomain.com>'
|
||||
$Password='<administrator or user password>'| `
|
||||
ConvertTo-SecureString -Force -AsPlainText
|
||||
$Credential= New-Object PSCredential($UserName,$Password)
|
||||
Login-AzureRmAccount -EnvironmentName "AzureStackAdmin" -TenantId $TenantID -Credential $Credential
|
||||
```
|
||||
|
||||
2. Now, let's access the storage account to hold this package. If you recall, we named the storage account **tenantartifacts** and this is located in a dedicated **resource group** of the same name:
|
||||
|
||||
``` powershell
|
||||
$StorageAccount = Get-AzureRmStorageAccount -ResourceGroupName tenantartifacts -Name tenantartifacts
|
||||
$GalleryContainer = Get-AzureStorageContainer -Name gallery -Context $StorageAccount.Context
|
||||
```
|
||||
3. With the resource group, storage account and gallery container now accessible, we can push our new Puppet Enterprise marketplace package into Azure Stack.
|
||||
|
||||
``` powershell
|
||||
$GalleryContainer | Set-AzureStorageBlobContent -File "C:\MyMarketPlaceItems\Puppet.PuppetEnterprise.1.0.0.azpkg"
|
||||
$GalleryItemURI = (Get-AzureStorageBlob -Context $StorageAccount.Context -Blob 'Puppet.PuppetEnterprise.1.0.0.azpkg' -Container 'gallery').ICloudBlob.uri.AbsoluteUri
|
||||
Add-AzureRMGalleryItem -GalleryItemUri $GalleryItemURI -Verbose
|
||||
```
|
||||
|
||||
When successful, you should see a **StatusCode** of **Created**
|
||||
|
||||
![Successful Upload](/deploy/azurestack/docs/media/PSCreated.PNG)
|
||||
|
||||
Go back and refresh the portal, and under **New -> Virtual Machines -> See All**, you should see your newly added Puppet Enterprise marketplace item
|
||||
|
||||
![Puppet added to Marketplace](/deploy/azurestack/docs/media/PuppetMarketplace.png)
|
||||
|
||||
With your newly created marketplace item created and pushed to the Azure Stack Marketplace, we're ready to deploy an instance of the environment.
|
||||
|
||||
1. On the **MAS-CON01** machine, in your Azure Stack portal, click on **New**, then **Virtual Machines**, then **See all**.
|
||||
2. Select the **Puppet Enterprise** item in the marketplace, and click **Create**.
|
||||
3. Provide the information for the following fields:
|
||||
- **PMADMINPASSWORD** - choose a password of your choice.
|
||||
- **PMDNSNAMEFORPUBLICIP** - for testing purposes, use **puppetmaster**.
|
||||
- **PMCONSOLEPASSWORD** - choose a password of your choice.
|
||||
- **Resource Group** - for testing purposes, use **puppet**.
|
||||
- **Location** - seeing as this is Azure Stack, you'll just be able to choose local in the current technical preview.
|
||||
|
||||
Once you've filled in the fields, it should look like this:
|
||||
|
||||
![Deploying Puppet](/deploy/azurestack/docs/media/PuppetDeploy.png)
|
||||
|
||||
4. Click **OK** to confirm the parameters, and then **Create** to start the deployment.
|
||||
|
||||
Depending on your hardware, the deployment of the key artifacts, the virtual machine, and its respective automated configuration, may take a while. Expect around 20-30 mins for the deployment, unless you have new hardware, and a bank of SSDs for storage!
|
||||
Once the deployment has completed, you're ready to proceed with configuring your Puppet Enterprise Master.
|
||||
|
||||
## Puppet Enterprise Master Setup | Final Steps
|
||||
Regardless of using Option 1, or Option 2, your Puppet Enterprise Master should now be deployed. You can now continue with the configuration of the Puppet Enterprise environment specifically.
|
||||
|
||||
1. In the Azure Stack portal, click on **Resource Groups** and locate the **puppet** resource group.
|
||||
2. Inside the resource group, click on the **puppetmaster** virtual machine, and take note of its **Public IP address/DNS name label**
|
||||
|
||||
![Deploying Puppet](/deploy/azurestack/docs/media/PuppetIP.PNG)
|
||||
|
||||
The _dnsaddress_ will be of the form _machinename_._local_.cloudapp.azurestack.external. Open a browser to https://_dnsaddress_. (Make sure you're going to http__s__, not http). You will be prompted about an invalid certificate - it is safe to ignore this for the purposes of this lab. If the Puppet configuration has succeeded, you should see the Puppet Console sign in page:
|
||||
|
||||
![Puppet Login](/deploy/azurestack/docs/media/PuppetLogin.png)
|
||||
|
||||
3. On the Puppet Enterprise sign-in screen, enter the username `admin` and the password you set during the deployment. When you log in, you should see a page like this:
|
||||
|
||||
![Puppet Logged in](/deploy/azurestack/docs/media/PuppetLoggedIn.png)
|
||||
|
||||
Now that we're successfully logged into the Puppet Enterprise Master, we'll quickly deploy an additional virtual machine that will be used for configuration tasks with Puppet.
|
||||
|
||||
## Provisioning the Parts Unlimited MRP Node | Deployment Options
|
||||
|
||||
Now that you have your Puppet Enterprise Master deployed, the fastest way to bring another node under its management will be to deploy an additional VM, into the **same resource group** and the **same virtual network**. That way, the 2 VMs can talk to one another easily, resolve DNS easily etc. It also simplifies management with them within this small POC network.
|
||||
|
||||
Now in order to streamline this, I've created an ARM template for you to use - all you need to do is grab it from here:
|
||||
|
||||
- **[Additional Puppet Node](/deploy/azurestack/instances/puppet_node/AddPuppetNode.json)**
|
||||
|
||||
Alternatively, for those of you who like to press buttons, and would like a simple option for deploying without copying and pasting, click the button below from your **MAS-CON01** machine, and fill in the parameter fields. The link should open the Azure Stack admin portal, and if you're not already logged in, it'll prompt you for your Azure Stack credentials, then take you immediately to the custom template blade:
|
||||
|
||||
<a href="https://adminportal.local.azurestack.external/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FMicrosoft%2FPartsUnlimitedMRP%2Fmaster%2Fdeploy%2Fazurestack%2Finstances%2Fpuppet_node%2FAddPuppetNode.json" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/azurestack/docs/media/DeployToStack.png"/>
|
||||
</a>
|
||||
|
||||
This node is based on the [Ubuntu base image that we added to the Azure Stack marketplace earlier](/deploy/azurestack/docs/add_marketplace_item.md). The only difference here is, the template creates the corresponding VM inside the same resource group, and virtual network as our Puppet Enterprise Master, and opens a couple of necessary ports in the network security group.
|
||||
|
||||
You'll need to enter information for the following fields:
|
||||
- **ADMINUSERNAME** - accept the default of **localadmin**.
|
||||
- **ADMINPASSWORD** - choose a password of your choice.
|
||||
- **DNSNAMEFORPUBLICIP** - for testing purposes, use **puppetnode1**.
|
||||
- **Resource Group** - for testing purposes, select existing, and use the drop down to select **puppet**.
|
||||
- **Location** - this will already be selected based on the resource group you choose.
|
||||
|
||||
![MRP Deployment](/deploy/azurestack/docs/media/AddPuppetNode.PNG)
|
||||
|
||||
If you're interested in taking a deeper look at the ARM template that is used for deployment, you could either **click Edit Template** within the custom template deployment blade, and that will present the template that will be used for the deployment.
|
||||
|
||||
Depending on your hardware, the deployment of the virtual machine, and its respective automated configuration, may take a while. Expect around 20-30 mins for the deployment, unless you have new hardware, and a bank of SSDs for storage!
|
||||
|
||||
Once the deployment has completed, you're ready to proceed with configuring the Puppet Master.
|
||||
|
||||
# Next steps
|
||||
|
||||
In this lab, you learned how to setup deploy Puppet Enterprise on Azure Stack, and deploy an initial node that will be configured with Puppet Enterprise. In the next lab, you'll walk through deploying the Parts Unlimited MRP app, to this node, from Puppet Enterprise.
|
||||
|
||||
- [Parts Unlimited MRP Continous Deployment with Puppet Enterprise](/deploy/azurestack/docs/puppet_CD.md)
|
||||
|
||||
## Continuous Feedback
|
||||
|
||||
#### Issues / Questions about this Hands-On-Lab?
|
||||
|
||||
[If you are encountering issues or have questions during this Hands on Labs, please open an issue by clicking here](https://github.com/Microsoft/PartsUnlimitedMRP/issues)
|
|
@ -1,53 +1,13 @@
|
|||
#Getting Started with DevOps on Azure Stack#
|
||||
# Getting Started with DevOps on Azure Stack
|
||||
|
||||
In order to get started exploring DevOps tooling on Azure Stack, you're going to need an Azure Stack, and that requires some hardware. If you're not sure what specific hardware you'll need for the single-node POC configuration, don't fear, it's all [documented here]
|
||||
(https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-deploy).
|
||||
In order to get started exploring DevOps tooling on Azure Stack, you're going to need an Azure Stack, and that requires some hardware. If you're not sure what specific hardware you'll need for the single-node POC configuration, don't fear, it's all [documented here](https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-deploy).
|
||||
|
||||
Once you've sourced your hardware, you'll need to [pull down the package](https://azure.microsoft.com/en-us/overview/azure-stack/try/?v=try), which requires you to complete a short registration form, then download the bits. A word of warning though - it's a 20GB file, so set aside a bit of time for a coffee, or 9.
|
||||
Once you've sourced your hardware, you'll need to [pull down the package](https://azure.microsoft.com/en-us/overview/azure-stack/try/?v=try), which requires you to complete a short registration form, then download the bits. A word of warning though - it's a big file, so set aside a bit of time for a coffee, or 9.
|
||||
|
||||
With the package safely downloaded, [follow the documentation](https://docs.microsoft.com/en-us/azure/azure-stack/azure-stack-run-powershell-script) to prepare your deployment machine, extract the necessary bits, and then run the PowerShell deployment script which will essentially deploy Azure Stack on your hardware. A couple of hours later, you'll have yourself an Azure Stack! There are a few examples of deployments scripts within the official documentation that should help you configure your Azure Stack deployment optimally, specifically around the use of Static IP addresses, the use of a Time Server etc. Read the docs carefully.
|
||||
|
||||
Make sure you pay particularly close attention to the password expiration configuration, as you don't want your POC machine to expire too soon!
|
||||
Make sure you pay particularly close attention to the portal activation, and also the password expiration configuration, as you don't want your POC machine to expire too soon!
|
||||
|
||||
# Next Step
|
||||
|
||||
Once your deployment has completed, we can move on to [connecting to Azure Stack](/deploy/azurestack/docs/connect_to_azurestack.md), and from there, we'll upload some images that you can use with the DevOps tools we'll be deploying.
|
||||
|
||||
##*Important Note for Azure Stack TP2 & Static IP Addresses#
|
||||
|
||||
When you deployed your Azure Stack, if you deployed with a static network configuration, there is a known issue, and workaround. If you're not sure whether you deployed with a static network configuration, essentially, you have a static configuration if you used any of the following parameters within your deployment script:
|
||||
|
||||
- NatIPv4Subnet
|
||||
- NatIPv4Address
|
||||
- NatIPv4DefaultGateway
|
||||
|
||||
###Known Issue#
|
||||
|
||||
If you deployed an Azure Stack TP2 One-Node environment with a static network configuration, you have 10 days to activate the MAS-BGPNAT01 VM, before it is no longer licensed. If the MAS-BGPNAT01 VM is off for an extended period, your environment may no longer function, even if it is activated/licensed and running.
|
||||
|
||||
###Resolution#
|
||||
|
||||
To update the static network configuration and activate the MAS-BGPNAT01 VM, take the following steps:
|
||||
|
||||
- From Hyper-V, Connect to and Login to the MAS-BGPNAT01 VM as azurestack\administrator (switch users from azurestack\fabricadmin)
|
||||
- Open PowerShell ISE (this will open as Administrator, which is required)
|
||||
- Create a new file, paste (from Clipboard via Hyper-V console) in and Run the following script (to eliminate any strange characters coming through on the copy/paste from this page, it is recommended that you copy from here, paste into notepad, then into PowerShell ISE):
|
||||
|
||||
```PowerShell
|
||||
$NetNatName = "BGPNAT"
|
||||
$NetNatEA = Get-NetNatExternalAddress -NatName $NetNatName
|
||||
$IPAddress = $NetNatEA.IPAddress
|
||||
$ExternalAddressID = $NetNatEA.ExternalAddressID
|
||||
$IPAddressConfig = Get-NetIPAddress -IPAddress $IPAddress
|
||||
$InterfaceAlias = $IPAddressConfig.InterfaceAlias
|
||||
$PrefixLength = $IPAddressConfig.PrefixLength
|
||||
Remove-NetNatExternalAddress -ExternalAddressID $ExternalAddressID -Confirm:$false
|
||||
New-NetIPAddress -InterfaceAlias $InterfaceAlias -IPAddress $IPAddress -PrefixLength $PrefixLength
|
||||
Add-NetNatExternalAddress -NatName $NetNatName -IPAddress $IPAddress -PortStart 4096 -PortEnd 49151
|
||||
```
|
||||
|
||||
Wait for the network/internet connection to return. Sometime soon after the script is run, the Network task bar icon will go from warning to clear. At this point, you can check the System settings for activation – it will attempt to activate on its own, or you can choose to activate it manually. The desired end state after these actions is as follows:
|
||||
|
||||
- Logoff the MAS-BGPNAT01 VM
|
||||
- Verify that you can continue to use the Portal / API for your Azure Stack TP2 One-Node environment
|
||||
- If you can no longer access the Portal / API for your environment (and you are past the 10-day grace period), you will have to redeploy, and then perform the above steps within the initial 10-day grace period
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"longSummary": "Parts Unlimited MRP and Jenkins on Ubuntu 14.04-LTS VMs for use with DevOps Hands-on-Labs.",
|
||||
"description": "<p>Jenkins is a leading open source automation server. Jenkins provides hundreds of plugins to support building, deploying and automating any project.</p><p>This VM contains the latest version of Jenkins, along with the MRP VM, both running on Ubuntu 14.04-LTS, configured as a single deployment, and will allow you to get started learning and understanding how to use Jenkins to deploy the Parts Unlimited MRP app.</p><p>For more information, review the links below.</p>",
|
||||
"documentationLink": "Jenkins Homepage",
|
||||
"documentationLink2": "Jenkins Documentation"
|
||||
"documentationLink2": "Jenkins Documentation",
|
||||
"documentationLink3": "Parts Unlimited MRP Documentation",
|
||||
"documentationLink4": "Parts Unlimited MRP Channel 9 Videos"
|
||||
}
|
||||
}
|
||||
|
|
Двоичные данные
deploy/azurestack/instances/jenkins_standalone/TheJenkinsProject.Jenkins.1.0.0.azpkg
Normal file
|
@ -0,0 +1,270 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"jenkinsAdminUsername": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"metadata": {
|
||||
"description": "User name for the Jenkins Master Virtual Machine."
|
||||
},
|
||||
"defaultValue": "jenkinsadmin"
|
||||
},
|
||||
"jenkinsAdminPassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "Password for the Jenkins Master Virtual Machine."
|
||||
}
|
||||
},
|
||||
"jenkinsDnsNameForPublicIP": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"metadata": {
|
||||
"description": "Globally unique DNS Name for the Public IP used to access the Jenkins Master Virtual Machine."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"jenkinsImagePublisher": "Canonical",
|
||||
"jenkinsImageOffer": "UbuntuServer",
|
||||
"jenkinsImageSku": "16.04.3-LTS",
|
||||
"jenkinsOSDiskName": "jenkinsOsdisk",
|
||||
"jenkinsNicName": "jenkinsNic",
|
||||
"addressPrefix": "10.0.0.0/16",
|
||||
"subnetName": "Subnet",
|
||||
"subnetPrefix": "10.0.0.0/24",
|
||||
"storageName": "[concat('vhdstorage', uniqueString(resourceGroup().id))]",
|
||||
"storageType": "Standard_LRS",
|
||||
"publicIPAddressType": "Dynamic",
|
||||
"vhdStorageContainerName": "vhds",
|
||||
"jenkinsNsgName": "jenkinsNSG",
|
||||
"jenkinsVmSize": "Standard_A3",
|
||||
"jenkinsVmName": "[toLower(parameters('jenkinsDnsNameForPublicIP'))]",
|
||||
"virtualNetworkName": "jenkinsVNET",
|
||||
"vnetId": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
|
||||
"subnetRef": "[concat(variables('vnetId'), '/subnets/', variables('subnetName'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[toLower(variables('storageName'))]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "StorageAccount"
|
||||
},
|
||||
"properties": {
|
||||
"accountType": "[variables('storageType')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('jenkinsNsgName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "NSG-Jenkins"
|
||||
},
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "SSH",
|
||||
"properties": {
|
||||
"description": "SSH port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "22",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1000,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Jenkins",
|
||||
"properties": {
|
||||
"description": "Jenkins port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "8080",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1100,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[parameters('jenkinsDnsNameForPublicIP')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "PublicIPAddress-Jenkins"
|
||||
},
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[parameters('jenkinsDnsNameForPublicIP')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[variables('virtualNetworkName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "VirtualNetwork"
|
||||
},
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[variables('jenkinsNicName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "NIC-Jenkins"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', parameters('jenkinsDnsNameForPublicIP'))]",
|
||||
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
|
||||
"[concat('Microsoft.Network/networkSecurityGroups/', variables('jenkinsNSGName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('jenkinsNSGName'))]"
|
||||
},
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('jenkinsDnsNameForPublicIP'))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[variables('jenkinsVmName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "VM-Jenkins"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageName'))]",
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('jenkinsNicName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('jenkinsVmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[variables('jenkinsVmName')]",
|
||||
"adminUsername": "[parameters('jenkinsAdminUsername')]",
|
||||
"adminPassword": "[parameters('jenkinsAdminPassword')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('jenkinsImagePublisher')]",
|
||||
"offer": "[variables('jenkinsImageOffer')]",
|
||||
"sku": "[variables('jenkinsImageSku')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "osdisk",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('vhdStorageContainerName'),'/',variables('jenkinsOSDiskName'),'.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('jenkinsNicName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "true",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('jenkinsVmName'),'/CustomScriptForLinux')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('jenkinsVmName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.3",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"fileUris": [
|
||||
"https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/azurestack/customscripts/jenkins/install_jenkins_1604.sh"
|
||||
],
|
||||
"commandToExecute": "bash install_jenkins_1604.sh"
|
||||
},
|
||||
"protectedSettings": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('jenkinsVmName'),'/LinuxVMAccessExtension')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('jenkinsVmName'),'/extensions/CustomScriptForLinux')]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "VMAccessForLinux",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"autoUpgradeMinorVersion": "true",
|
||||
"settings": {},
|
||||
"protectedSettings": {
|
||||
"username": "[parameters('jenkinsAdminUsername')]",
|
||||
"password": "[parameters('jenkinsAdminPassword')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
До Ширина: | Высота: | Размер: 90 KiB После Ширина: | Высота: | Размер: 90 KiB |
Двоичные данные
deploy/azurestack/instances/jenkins_standalone/TheJenkinsProject.Jenkins/Icons/Large.png
Normal file
После Ширина: | Высота: | Размер: 9.6 KiB |
Двоичные данные
deploy/azurestack/instances/jenkins_standalone/TheJenkinsProject.Jenkins/Icons/Medium.png
Normal file
После Ширина: | Высота: | Размер: 6.7 KiB |
Двоичные данные
deploy/azurestack/instances/jenkins_standalone/TheJenkinsProject.Jenkins/Icons/Small.png
Normal file
После Ширина: | Высота: | Размер: 2.1 KiB |
Двоичные данные
deploy/azurestack/instances/jenkins_standalone/TheJenkinsProject.Jenkins/Icons/Wide.png
Normal file
После Ширина: | Высота: | Размер: 9.9 KiB |
|
@ -0,0 +1,37 @@
|
|||
{ "$schema": "https://gallery.azure.com/schemas/2014-09-01/manifest.json#",
|
||||
"name": "Jenkins",
|
||||
"publisher": "TheJenkinsProject",
|
||||
"version": "1.0.0",
|
||||
"displayName": "ms-resource:displayName",
|
||||
"publisherDisplayName": "ms-resource:publisherDisplayName",
|
||||
"publisherLegalName": "ms-resource:publisherDisplayName",
|
||||
"summary": "ms-resource:summary",
|
||||
"longSummary": "ms-resource:longSummary",
|
||||
"description": "ms-resource:description",
|
||||
"longDescription": "ms-resource:description",
|
||||
"links": [
|
||||
{ "displayName": "ms-resource:documentationLink", "uri": "https://jenkins.io/index.html" },
|
||||
{ "displayName": "ms-resource:documentationLink2", "uri": "https://jenkins.io/doc/" }
|
||||
],
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "JenkinsDeploy",
|
||||
"type": "Template",
|
||||
"path": "DeploymentTemplates\\JenkinsDeploy.json",
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"icons": {
|
||||
"small": "Icons\\Small.png",
|
||||
"medium": "Icons\\Medium.png",
|
||||
"large": "Icons\\Large.png",
|
||||
"wide": "Icons\\Wide.png",
|
||||
"hero": "Icons\\Hero.png"
|
||||
},
|
||||
"categories": [
|
||||
"Compute"
|
||||
],
|
||||
"uiDefinition": {
|
||||
"path": "UIDefinition.json"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"displayName": "Jenkins",
|
||||
"publisherDisplayName": "The Jenkins Project",
|
||||
"summary": "Jenkins on Ubuntu 16.04-LTS VM, pre-configured and ready to run on Azure Stack",
|
||||
"longSummary": "Jenkins on Ubuntu 16.04-LTS VM, pre-configured and ready to run on Azure Stack",
|
||||
"description": "<p>The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project.</p><p>This VM contains the latest version of Jenkins, running on Ubuntu 14.04-LTS, configured as a single, standalone installation and will allow you to get started learning and understanding key Jenkins tasks.</p><p>For more information, review the links below.</p>",
|
||||
"documentationLink": "The Jenkins Project",
|
||||
"documentationLink2": "Jenkins Documentation"
|
||||
}
|
Двоичные данные
deploy/azurestack/instances/parts_unlimited_SSH_mrp_base/PartsUnlimited.MRPSSH.1.0.0.azpkg
Normal file
|
@ -0,0 +1,275 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"mrpAdminUsername": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"metadata": {
|
||||
"description": "User name for the MRP Virtual Machine."
|
||||
},
|
||||
"defaultValue": "mrpadmin"
|
||||
},
|
||||
"adminPublicKey": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "SSH rsa public key file as a string"
|
||||
}
|
||||
},
|
||||
"mrpDnsNameForPublicIP": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"metadata": {
|
||||
"description": "Globally unique DNS Name for the Public IP used to access the MRP Virtual Machine."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"mrpImagePublisher": "Canonical",
|
||||
"mrpImageOffer": "UbuntuServer",
|
||||
"mrpImageSku": "16.04.3-LTS",
|
||||
"mrpOSDiskName": "mrpOsdisk",
|
||||
"mrpNicName": "mrpNic",
|
||||
"addressPrefix": "10.0.0.0/16",
|
||||
"subnetName": "Subnet",
|
||||
"subnetPrefix": "10.0.0.0/24",
|
||||
"storageName": "[concat('vhdstorage', uniqueString(resourceGroup().id))]",
|
||||
"storageType": "Standard_LRS",
|
||||
"publicIPAddressType": "Dynamic",
|
||||
"vhdStorageContainerName": "vhds",
|
||||
"mrpNsgName": "mrpNSG",
|
||||
"mrpVmSize": "Standard_A2",
|
||||
"mrpVmName": "[toLower(parameters('mrpDnsNameForPublicIP'))]",
|
||||
"sshKeyPath": "[concat('/home/',parameters('mrpAdminUsername'),'/.ssh/authorized_keys')]",
|
||||
"virtualNetworkName": "mrpVNET",
|
||||
"vnetId": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
|
||||
"subnetRef": "[concat(variables('vnetId'), '/subnets/', variables('subnetName'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[toLower(variables('storageName'))]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "StorageAccount"
|
||||
},
|
||||
"properties": {
|
||||
"accountType": "[variables('storageType')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('mrpNsgName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "NSG-mrp"
|
||||
},
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "SSH",
|
||||
"properties": {
|
||||
"description": "SSH port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "22",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1000,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MRP",
|
||||
"properties": {
|
||||
"description": "MRP port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "9080",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1100,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OrderingSvc",
|
||||
"properties": {
|
||||
"description": "OrderingService port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "8080",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1200,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[parameters('mrpDnsNameForPublicIP')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "PublicIPAddress-mrp"
|
||||
},
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[parameters('mrpDnsNameForPublicIP')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[variables('virtualNetworkName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "VirtualNetwork"
|
||||
},
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[variables('mrpNicName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "NIC-mrp"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', parameters('mrpDnsNameForPublicIP'))]",
|
||||
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
|
||||
"[concat('Microsoft.Network/networkSecurityGroups/', variables('mrpNSGName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('mrpNSGName'))]"
|
||||
},
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('mrpDnsNameForPublicIP'))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[variables('mrpVmName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "VM-mrp"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageName'))]",
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('mrpNicName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('mrpVmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[variables('mrpVmName')]",
|
||||
"adminUsername": "[parameters('mrpAdminUsername')]",
|
||||
"linuxConfiguration": {
|
||||
"disablePasswordAuthentication": "true",
|
||||
"ssh": {
|
||||
"publicKeys": [
|
||||
{
|
||||
"path": "[variables('sshKeyPath')]",
|
||||
"keyData": "[parameters('adminPublicKey')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('mrpImagePublisher')]",
|
||||
"offer": "[variables('mrpImageOffer')]",
|
||||
"sku": "[variables('mrpImageSku')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "osdisk",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('vhdStorageContainerName'),'/',variables('mrpOSDiskName'),'.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('mrpNicName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "true",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('mrpVmName'),'/mrpsetup')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('mrpVmName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.3",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"fileUris": [
|
||||
"https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/azurestack/instances/parts_unlimited_mrp_base/install_mrp_dependencies_1604.sh"
|
||||
],
|
||||
"commandToExecute": "bash install_mrp_dependencies_1604.sh"
|
||||
},
|
||||
"protectedSettings": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
До Ширина: | Высота: | Размер: 90 KiB После Ширина: | Высота: | Размер: 90 KiB |
Двоичные данные
deploy/azurestack/instances/parts_unlimited_SSH_mrp_base/PartsUnlimitedSSH.Ubuntu1604/Icons/Large.png
Normal file
После Ширина: | Высота: | Размер: 3.3 KiB |
Двоичные данные
deploy/azurestack/instances/parts_unlimited_SSH_mrp_base/PartsUnlimitedSSH.Ubuntu1604/Icons/Medium.png
Normal file
После Ширина: | Высота: | Размер: 2.5 KiB |
Двоичные данные
deploy/azurestack/instances/parts_unlimited_SSH_mrp_base/PartsUnlimitedSSH.Ubuntu1604/Icons/Small.png
Normal file
После Ширина: | Высота: | Размер: 997 B |
Двоичные данные
deploy/azurestack/instances/parts_unlimited_SSH_mrp_base/PartsUnlimitedSSH.Ubuntu1604/Icons/Wide.png
Normal file
После Ширина: | Высота: | Размер: 3.5 KiB |
|
@ -0,0 +1,37 @@
|
|||
{ "$schema": "https://gallery.azure.com/schemas/2014-09-01/manifest.json#",
|
||||
"name": "MRPSSH",
|
||||
"publisher": "PartsUnlimited",
|
||||
"version": "1.0.0",
|
||||
"displayName": "ms-resource:displayName",
|
||||
"publisherDisplayName": "ms-resource:publisherDisplayName",
|
||||
"publisherLegalName": "ms-resource:publisherDisplayName",
|
||||
"summary": "ms-resource:summary",
|
||||
"longSummary": "ms-resource:longSummary",
|
||||
"description": "ms-resource:description",
|
||||
"longDescription": "ms-resource:description",
|
||||
"links": [
|
||||
{ "displayName": "ms-resource:documentationLink", "uri": "https://microsoft.github.io/PartsUnlimitedMRP/" },
|
||||
{ "displayName": "ms-resource:documentationLink2", "uri": "https://channel9.msdn.com/Series/Parts-Unlimited-MRP-Labs" }
|
||||
],
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "PartsUnlimitedSSHMRP",
|
||||
"type": "Template",
|
||||
"path": "DeploymentTemplates\\PartsUnlimitedSSHMRP.json",
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"icons": {
|
||||
"small": "Icons\\Small.png",
|
||||
"medium": "Icons\\Medium.png",
|
||||
"large": "Icons\\Large.png",
|
||||
"wide": "Icons\\Wide.png",
|
||||
"hero": "Icons\\Hero.png"
|
||||
},
|
||||
"categories": [
|
||||
"Compute"
|
||||
],
|
||||
"uiDefinition": {
|
||||
"path": "UIDefinition.json"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"displayName": "Parts Unlimited MRP with SSH",
|
||||
"publisherDisplayName": "Parts Unlimited",
|
||||
"summary": "Parts Unlimited MRP Virtual Machine with SSH for use with DevOps Hands-on-Labs.",
|
||||
"longSummary": "Parts Unlimited MRP Virtual Machine with SSH for use with DevOps Hands-on-Labs.",
|
||||
"description": "<p>Parts Unlimited MRP is a fictional outsourced Manufacturing Resource Planning (MRP) application for training purposes based on the description in chapters 31-35 of The Phoenix Projectby Gene Kim, Kevin Behr and George Spafford. © 2013 IT Revolution Press LLC, Portland, OR. Resemblance to “Project Unicorn” in the novel is intentional; resemblance to any real company is purely coincidental. </p><p>The application uses entirely open source software including Linux, Java, Apache, and MongoDB which creates a web front end, an order service, and an integration service</p><p>For more information, review the links below.",
|
||||
"documentationLink": "Documentation",
|
||||
"documentationLink2": "Channel 9 Videos"
|
||||
}
|
Двоичные данные
deploy/azurestack/instances/parts_unlimited_mrp_base/PartsUnlimited.MRP.1.0.0.azpkg
Normal file
|
@ -0,0 +1,265 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"mrpAdminUsername": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"metadata": {
|
||||
"description": "User name for the MRP Virtual Machine."
|
||||
},
|
||||
"defaultValue": "mrpadmin"
|
||||
},
|
||||
"mrpAdminPassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "Administrator password for the MRP Virtual Machine."
|
||||
}
|
||||
},
|
||||
"mrpDnsNameForPublicIP": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"metadata": {
|
||||
"description": "Globally unique DNS Name for the Public IP used to access the MRP Virtual Machine."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"mrpImagePublisher": "Canonical",
|
||||
"mrpImageOffer": "UbuntuServer",
|
||||
"mrpImageSku": "16.04.3-LTS",
|
||||
"mrpOSDiskName": "mrpOsdisk",
|
||||
"mrpNicName": "mrpNic",
|
||||
"addressPrefix": "10.0.0.0/16",
|
||||
"subnetName": "Subnet",
|
||||
"subnetPrefix": "10.0.0.0/24",
|
||||
"storageName": "[concat('vhdstorage', uniqueString(resourceGroup().id))]",
|
||||
"storageType": "Standard_LRS",
|
||||
"publicIPAddressType": "Dynamic",
|
||||
"vhdStorageContainerName": "vhds",
|
||||
"mrpNsgName": "mrpNSG",
|
||||
"mrpVmSize": "Standard_A2",
|
||||
"mrpVmName": "[toLower(parameters('mrpDnsNameForPublicIP'))]",
|
||||
"virtualNetworkName": "mrpVNET",
|
||||
"vnetId": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
|
||||
"subnetRef": "[concat(variables('vnetId'), '/subnets/', variables('subnetName'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[toLower(variables('storageName'))]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"accountType": "[variables('storageType')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('mrpNsgName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "SSH",
|
||||
"properties": {
|
||||
"description": "SSH port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "22",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1000,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MRP",
|
||||
"properties": {
|
||||
"description": "MRP port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "9080",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1100,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OrderingSvc",
|
||||
"properties": {
|
||||
"description": "OrderingService port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "8080",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1200,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[parameters('mrpDnsNameForPublicIP')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[parameters('mrpDnsNameForPublicIP')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[variables('virtualNetworkName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[variables('mrpNicName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', parameters('mrpDnsNameForPublicIP'))]",
|
||||
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
|
||||
"[variables('mrpNsgName')]"
|
||||
],
|
||||
"properties": {
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('mrpNsgName'))]"
|
||||
},
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses',parameters('mrpDnsNameForPublicIP'))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[variables('mrpVmName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageName'))]",
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('mrpNicName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('mrpVmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[variables('mrpVmName')]",
|
||||
"adminUsername": "[parameters('mrpAdminUsername')]",
|
||||
"adminPassword": "[parameters('mrpAdminPassword')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('mrpImagePublisher')]",
|
||||
"offer": "[variables('mrpImageOffer')]",
|
||||
"sku": "[variables('mrpImageSKU')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[concat(resourceGroup().name, 'osdisk')]",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('vhdStorageContainerName'),'/',variables('mrpOSDiskName'),'.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('mrpNicName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "true",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('mrpVmName'),'/LinuxCustomScriptExtension')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('mrpVmName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"fileUris": [
|
||||
"https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/azurestack/customscripts/install_updates.sh"
|
||||
],
|
||||
"commandToExecute": "bash install_updates.sh"
|
||||
},
|
||||
"protectedSettings": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('mrpVmName'),'/LinuxVMAccessExtension')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('mrpVmName'),'/extensions/LinuxCustomScriptExtension')]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "VMAccessForLinux",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"autoUpgradeMinorVersion": "true",
|
||||
"settings": {},
|
||||
"protectedSettings": {
|
||||
"username": "[parameters('mrpAdminUsername')]",
|
||||
"password": "[parameters('mrpAdminPassword')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
Двоичные данные
deploy/azurestack/instances/parts_unlimited_mrp_base/PartsUnlimited.Ubuntu1604/Icons/Hero.png
Normal file
После Ширина: | Высота: | Размер: 90 KiB |
Двоичные данные
deploy/azurestack/instances/parts_unlimited_mrp_base/PartsUnlimited.Ubuntu1604/Icons/Large.png
Normal file
После Ширина: | Высота: | Размер: 3.3 KiB |
Двоичные данные
deploy/azurestack/instances/parts_unlimited_mrp_base/PartsUnlimited.Ubuntu1604/Icons/Medium.png
Normal file
После Ширина: | Высота: | Размер: 2.5 KiB |
Двоичные данные
deploy/azurestack/instances/parts_unlimited_mrp_base/PartsUnlimited.Ubuntu1604/Icons/Small.png
Normal file
После Ширина: | Высота: | Размер: 997 B |
Двоичные данные
deploy/azurestack/instances/parts_unlimited_mrp_base/PartsUnlimited.Ubuntu1604/Icons/Wide.png
Normal file
После Ширина: | Высота: | Размер: 3.5 KiB |
|
@ -0,0 +1,37 @@
|
|||
{ "$schema": "https://gallery.azure.com/schemas/2014-09-01/manifest.json#",
|
||||
"name": "MRP",
|
||||
"publisher": "PartsUnlimited",
|
||||
"version": "1.0.0",
|
||||
"displayName": "ms-resource:displayName",
|
||||
"publisherDisplayName": "ms-resource:publisherDisplayName",
|
||||
"publisherLegalName": "ms-resource:publisherDisplayName",
|
||||
"summary": "ms-resource:summary",
|
||||
"longSummary": "ms-resource:longSummary",
|
||||
"description": "ms-resource:description",
|
||||
"longDescription": "ms-resource:description",
|
||||
"links": [
|
||||
{ "displayName": "ms-resource:documentationLink", "uri": "https://microsoft.github.io/PartsUnlimitedMRP/" },
|
||||
{ "displayName": "ms-resource:documentationLink2", "uri": "https://channel9.msdn.com/Series/Parts-Unlimited-MRP-Labs" }
|
||||
],
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "PartsUnlimitedMRP",
|
||||
"type": "Template",
|
||||
"path": "DeploymentTemplates\\PartsUnlimitedMRP.json",
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"icons": {
|
||||
"small": "Icons\\Small.png",
|
||||
"medium": "Icons\\Medium.png",
|
||||
"large": "Icons\\Large.png",
|
||||
"wide": "Icons\\Wide.png",
|
||||
"hero": "Icons\\Hero.png"
|
||||
},
|
||||
"categories": [
|
||||
"Compute"
|
||||
],
|
||||
"uiDefinition": {
|
||||
"path": "UIDefinition.json"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"$schema": "https://gallery.azure.com/schemas/2015-02-12/UIDefinition.json#",
|
||||
"createDefinition": {
|
||||
"createBlade": {
|
||||
"name": "DeployFromTemplateBlade",
|
||||
"extension": "HubsExtension"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"displayName": "Parts Unlimited MRP",
|
||||
"publisherDisplayName": "Parts Unlimited",
|
||||
"summary": "Parts Unlimited MRP Virtual Machine for use with DevOps Hands-on-Labs.",
|
||||
"longSummary": "Parts Unlimited MRP Virtual Machine for use with DevOps Hands-on-Labs.",
|
||||
"description": "<p>Parts Unlimited MRP is a fictional outsourced Manufacturing Resource Planning (MRP) application for training purposes based on the description in chapters 31-35 of The Phoenix Projectby Gene Kim, Kevin Behr and George Spafford. © 2013 IT Revolution Press LLC, Portland, OR. Resemblance to “Project Unicorn” in the novel is intentional; resemblance to any real company is purely coincidental. </p><p>The application uses entirely open source software including Linux, Java, Apache, and MongoDB which creates a web front end, an order service, and an integration service</p><p>For more information, review the links below.",
|
||||
"documentationLink": "Documentation",
|
||||
"documentationLink2": "Channel 9 Videos"
|
||||
}
|
|
@ -12,5 +12,9 @@ apt-get install tomcat7 -y
|
|||
apt-get install wget -y
|
||||
|
||||
# Set Java environment variables
|
||||
sed -i '$ a JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64' /etc/default/tomcat7
|
||||
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
|
||||
export PATH=$PATH:/usr/lib/jvm/java-8-openjdk-amd64/bin
|
||||
|
||||
# Restart tomcat7
|
||||
service tomcat7 restart
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,261 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"adminUsername": {
|
||||
"defaultValue": "localadmin",
|
||||
"minLength": 1,
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "User name for the additional node."
|
||||
}
|
||||
},
|
||||
"adminPassword": {
|
||||
"type": "SecureString",
|
||||
"metadata": {
|
||||
"description": "Administrator password for the additional node."
|
||||
}
|
||||
},
|
||||
"dnsNameForPublicIP": {
|
||||
"minLength": 1,
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "Globally unique DNS Name for the Public IP used to access the MRP Virtual Machine."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"imagePublisher": "Canonical",
|
||||
"imageOffer": "UbuntuServer",
|
||||
"imageSku": "16.04.3-LTS",
|
||||
"osDiskName": "[tolower(concat(parameters('dnsNameForPublicIP'), 'osdisk'))]",
|
||||
"nicName": "[tolower(concat(parameters('dnsNameForPublicIP'), 'Nic'))]",
|
||||
"addressPrefix": "10.0.0.0/16",
|
||||
"subnetName": "Subnet",
|
||||
"subnetPrefix": "10.0.0.0/24",
|
||||
"storageName": "[tolower(concat(parameters('dnsNameForPublicIP'), 'sa'))]",
|
||||
"storageType": "Standard_LRS",
|
||||
"publicIPAddressType": "Dynamic",
|
||||
"vhdStorageContainerName": "vhds",
|
||||
"nsgName": "[tolower(concat(parameters('dnsNameForPublicIP'), 'NSG'))]",
|
||||
"vmSize": "Standard_A2",
|
||||
"vmName": "[toLower(parameters('dnsNameForPublicIP'))]",
|
||||
"existingVirtualNetworkName": "puppetVNET",
|
||||
"vnetId": "[resourceId('Microsoft.Network/virtualNetworks', variables('existingVirtualNetworkName'))]",
|
||||
"subnetRef": "[concat(variables('vnetId'), '/subnets/', variables('subnetName'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[toLower(variables('storageName'))]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"accountType": "[variables('storageType')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('nsgName')]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "SSH",
|
||||
"properties": {
|
||||
"description": "SSH port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "22",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1000,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MRP",
|
||||
"properties": {
|
||||
"description": "MRP port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "9080",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1100,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OrderingSvc",
|
||||
"properties": {
|
||||
"description": "OrderingService port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "8080",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1200,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[tolower(concat(parameters('dnsNameForPublicIP'), 'publicIP'))]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[parameters('dnsNameForPublicIP')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[variables('existingVirtualNetworkName')]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[variables('nicName')]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"
|
||||
},
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', tolower(concat(parameters('dnsNameForPublicIP'), 'publicIP')))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', tolower(concat(parameters('dnsNameForPublicIP'), 'publicIP')))]",
|
||||
"[concat('Microsoft.Network/virtualNetworks/', variables('existingVirtualNetworkName'))]",
|
||||
"[variables('nsgName')]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[variables('vmName')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('vmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[variables('vmName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"adminPassword": "[parameters('adminPassword')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('imagePublisher')]",
|
||||
"offer": "[variables('imageOffer')]",
|
||||
"sku": "[variables('imageSKU')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[variables('osDiskName')]",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('vhdStorageContainerName'),'/',variables('osDiskName'),'.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "true",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageName'))]",
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('vmName'),'/LinuxCustomScriptExtension')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.5",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"commandToExecute": "ifconfig"
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('vmName'),'/LinuxVMAccessExtension')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "VMAccessForLinux",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"autoUpgradeMinorVersion": "true",
|
||||
"settings": {},
|
||||
"protectedSettings": {
|
||||
"username": "[parameters('adminUsername')]",
|
||||
"password": "[parameters('adminPassword')]"
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'),'/extensions/LinuxCustomScriptExtension')]"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
|
Двоичные данные
deploy/azurestack/instances/puppet_standalone/Puppet.PuppetEnterprise.1.0.0.azpkg
Normal file
|
@ -0,0 +1,306 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"pmAdminUsername": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"metadata": {
|
||||
"description": "User name for the Puppet Master Virtual Machine."
|
||||
},
|
||||
"defaultValue": "puppetadmin"
|
||||
},
|
||||
"pmAdminPassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "Password for the Puppet Master Virtual Machine."
|
||||
}
|
||||
},
|
||||
"pmDnsNameForPublicIP": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"metadata": {
|
||||
"description": "Globally unique DNS Name for the Public IP used to access the Puppet Master Virtual Machine."
|
||||
}
|
||||
},
|
||||
"pmConsolePassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "Password for the Puppet Master console admin account."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"pmImagePublisher": "Canonical",
|
||||
"pmImageOffer": "UbuntuServer",
|
||||
"pmImageSku": "16.04.3-LTS",
|
||||
"pmVersion": "2017.2.1",
|
||||
"pmOSDiskName": "puppetOsdisk",
|
||||
"pmNicName": "puppetNic",
|
||||
"addressPrefix": "10.0.0.0/16",
|
||||
"subnetName": "Subnet",
|
||||
"subnetPrefix": "10.0.0.0/24",
|
||||
"storageName": "[concat('vhdstorage', uniqueString(resourceGroup().id))]",
|
||||
"storageType": "Standard_LRS",
|
||||
"publicIPAddressType": "Dynamic",
|
||||
"vhdStorageContainerName": "vhds",
|
||||
"pmNsgName": "pmNSG",
|
||||
"pmVmSize": "Standard_A3",
|
||||
"pmVmName": "[toLower(parameters('pmDnsNameForPublicIP'))]",
|
||||
"virtualNetworkName": "puppetVNET",
|
||||
"vnetId": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
|
||||
"subnetRef": "[concat(variables('vnetId'), '/subnets/', variables('subnetName'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[toLower(variables('storageName'))]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "StorageAccount"
|
||||
},
|
||||
"properties": {
|
||||
"accountType": "[variables('storageType')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('pmNsgName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "NSG-Puppet"
|
||||
},
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "SSH",
|
||||
"properties": {
|
||||
"description": "SSH port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "22",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1000,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "HTTPS",
|
||||
"properties": {
|
||||
"description": "HTTPS port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "443",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1100,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Puppet",
|
||||
"properties": {
|
||||
"description": "Puppet port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "8140",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1200,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MCollective",
|
||||
"properties": {
|
||||
"description": "MCollective port",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "61613",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 1300,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[parameters('pmDnsNameForPublicIP')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "PublicIPAddress-Puppet"
|
||||
},
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[parameters('pmDnsNameForPublicIP')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[variables('virtualNetworkName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "VirtualNetwork"
|
||||
},
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[variables('pmNicName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "NIC-Puppet"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', parameters('pmDnsNameForPublicIP'))]",
|
||||
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
|
||||
"[concat('Microsoft.Network/networkSecurityGroups/', variables('pmNSGName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('pmNSGName'))]"
|
||||
},
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('pmDnsNameForPublicIP'))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[variables('pmVmName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"tags": {
|
||||
"displayName": "VM-Puppet"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageName'))]",
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('pmNicName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('pmVmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[variables('pmVmName')]",
|
||||
"adminUsername": "[parameters('pmAdminUsername')]",
|
||||
"adminPassword": "[parameters('pmAdminPassword')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('pmImagePublisher')]",
|
||||
"offer": "[variables('pmImageOffer')]",
|
||||
"sku": "[variables('pmImageSku')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "osdisk",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('vhdStorageContainerName'),'/',variables('pmOSDiskName'),'.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('pmNicName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "true",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('pmVmName'),'/CustomScriptForLinux')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('pmVmName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.3",
|
||||
"autoUpgradeMinorVersion": "true",
|
||||
|
||||
"settings": {
|
||||
"fileUris": [
|
||||
"https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/azurestack/customscripts/puppet/install_puppet_1604.sh"
|
||||
]
|
||||
},
|
||||
"protectedSettings": {
|
||||
"commandToExecute": "[concat('bash install_puppet_1604.sh ', variables('pmVersion'), ' ', parameters('pmConsolePassword'))]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('pmVmName'),'/LinuxVMAccessExtension')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('pmVmName'),'/extensions/CustomScriptForLinux')]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "VMAccessForLinux",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"autoUpgradeMinorVersion": "true",
|
||||
"settings": {},
|
||||
"protectedSettings": {
|
||||
"username": "[parameters('pmAdminUsername')]",
|
||||
"password": "[parameters('pmAdminPassword')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Двоичные данные
deploy/azurestack/instances/puppet_standalone/Puppet.PuppetEnterprise/Icons/Hero.png
Normal file
После Ширина: | Высота: | Размер: 90 KiB |
Двоичные данные
deploy/azurestack/instances/puppet_standalone/Puppet.PuppetEnterprise/Icons/Large.png
Normal file
После Ширина: | Высота: | Размер: 2.1 KiB |
Двоичные данные
deploy/azurestack/instances/puppet_standalone/Puppet.PuppetEnterprise/Icons/Medium.png
Normal file
После Ширина: | Высота: | Размер: 1.9 KiB |
Двоичные данные
deploy/azurestack/instances/puppet_standalone/Puppet.PuppetEnterprise/Icons/Small.png
Normal file
После Ширина: | Высота: | Размер: 958 B |
Двоичные данные
deploy/azurestack/instances/puppet_standalone/Puppet.PuppetEnterprise/Icons/Wide.png
Normal file
После Ширина: | Высота: | Размер: 2.4 KiB |
|
@ -0,0 +1,37 @@
|
|||
{ "$schema": "https://gallery.azure.com/schemas/2014-09-01/manifest.json#",
|
||||
"name": "PuppetEnterprise",
|
||||
"publisher": "Puppet",
|
||||
"version": "1.0.0",
|
||||
"displayName": "ms-resource:displayName",
|
||||
"publisherDisplayName": "ms-resource:publisherDisplayName",
|
||||
"publisherLegalName": "ms-resource:publisherDisplayName",
|
||||
"summary": "ms-resource:summary",
|
||||
"longSummary": "ms-resource:longSummary",
|
||||
"description": "ms-resource:description",
|
||||
"longDescription": "ms-resource:description",
|
||||
"links": [
|
||||
{ "displayName": "ms-resource:documentationLink", "uri": "https://puppet.com/" },
|
||||
{ "displayName": "ms-resource:documentationLink2", "uri": "https://docs.puppet.com/puppet/" }
|
||||
],
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "PuppetDeploy",
|
||||
"type": "Template",
|
||||
"path": "DeploymentTemplates\\PuppetDeploy.json",
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"icons": {
|
||||
"small": "Icons\\Small.png",
|
||||
"medium": "Icons\\Medium.png",
|
||||
"large": "Icons\\Large.png",
|
||||
"wide": "Icons\\Wide.png",
|
||||
"hero": "Icons\\Hero.png"
|
||||
},
|
||||
"categories": [
|
||||
"Compute"
|
||||
],
|
||||
"uiDefinition": {
|
||||
"path": "UIDefinition.json"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"$schema": "https://gallery.azure.com/schemas/2015-02-12/UIDefinition.json#",
|
||||
"createDefinition": {
|
||||
"createBlade": {
|
||||
"name": "DeployFromTemplateBlade",
|
||||
"extension": "HubsExtension"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"displayName": "Puppet Enterprise",
|
||||
"publisherDisplayName": "Puppet",
|
||||
"summary": "Puppet Enterprise on Ubuntu 16.04-LTS VM, pre-configured and ready to run on Azure Stack",
|
||||
"longSummary": "Puppet Enterprise on Ubuntu 16.04-LTS VM, pre-configured and ready to run on Azure Stack",
|
||||
"description": "<p>Puppet Enterprise lets you automate the entire lifecycle of your Azure infrastructure, simply, scalably, and securely, from initial provisioning through application deployment.</p><p>After you set up your Puppet Master, you can start automating common tasks, such as provisioning VMs, deploying an IIS site, and configuring a SQL server database.</p><p>For more information, review the links below.</p>",
|
||||
"documentationLink": "Puppet Enterprise",
|
||||
"documentationLink2": "Puppet Documentation"
|
||||
}
|
Двоичные данные
deploy/azurestack/instances/ubuntu_server_1604_base/Canonical.UbuntuServer.1.0.0.azpkg
Normal file
|
@ -0,0 +1,248 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"adminUsername": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Username for the Virtual Machine."
|
||||
},
|
||||
"defaultValue": "localadmin"
|
||||
},
|
||||
"adminPassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "Administrator password used when provisioning virtual machines"
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"dnsNameForPublicIP": "[resourceGroup().name]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"imagePublisher": "Canonical",
|
||||
"imageOffer": "UbuntuServer",
|
||||
"UbuntuSKU": "16.04.3-LTS",
|
||||
"OSDiskName": "[tolower(concat(resourceGroup().name, 'osdisk'))]",
|
||||
"nicName": "[tolower(concat(resourceGroup().name, 'vNic'))]",
|
||||
"addressPrefix": "10.0.0.0/24",
|
||||
"subnetName": "[tolower(concat(resourceGroup().name, 'subnet'))]",
|
||||
"subnetPrefix": "10.0.0.0/24",
|
||||
"storageAccountName": "[concat(resourceGroup().name, 'sa')]",
|
||||
"storageAccountType": "Standard_LRS",
|
||||
"publicIPAddressName": "[tolower(concat(resourceGroup().name, 'publicIP'))]",
|
||||
"publicIPAddressType": "Dynamic",
|
||||
"vmStorageAccountContainerName": "vhds",
|
||||
"vmName": "[resourceGroup().name]",
|
||||
"vmSize": "Standard_A2",
|
||||
"virtualNetworkName": "[tolower(concat(resourceGroup().name, 'vNet'))]",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
|
||||
"subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]",
|
||||
"networkSecurityGroupName": "[tolower(concat(resourceGroup().name, 'nsg'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[toLower(variables('storageAccountName'))]",
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"accountType": "[variables('storageAccountType')]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('networkSecurityGroupName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "ssh",
|
||||
"properties": {
|
||||
"description": "Allow SSH",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "22",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 200,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('publicIPAddressName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('dnsNameForPublicIP')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[variables('virtualNetworkName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-05-01-preview",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[variables('nicName')]",
|
||||
"location": "[variables('location')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
|
||||
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
|
||||
"[variables('networkSecurityGroupName')]"
|
||||
],
|
||||
"properties": {
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
|
||||
},
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"
|
||||
},
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2015-06-15",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[variables('vmName')]",
|
||||
"location": "[variables('location')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('vmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[variables('vmName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"adminPassword": "[parameters('adminPassword')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('imagePublisher')]",
|
||||
"offer": "[variables('imageOffer')]",
|
||||
"sku": "[variables('UbuntuSKU')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[concat(resourceGroup().name, 'osdisk')]",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": "true",
|
||||
"storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('vmName'),'/LinuxCustomScriptExtension')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.3",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"fileUris": [
|
||||
"https://raw.githubusercontent.com/Microsoft/PartsUnlimitedMRP/master/deploy/azurestack/customscripts/install_updates.sh"
|
||||
],
|
||||
"commandToExecute": "bash install_updates.sh"
|
||||
},
|
||||
"protectedSettings": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('vmName'),'/LinuxDockerExtension')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'),'/extensions/LinuxCustomScriptExtension')]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.Azure.Extensions",
|
||||
"type": "DockerExtension",
|
||||
"typeHandlerVersion": "1.2",
|
||||
"autoUpgradeMinorVersion": "true",
|
||||
"settings": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(variables('vmName'),'/LinuxVMAccessExtension')]",
|
||||
"apiVersion": "2015-06-15",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'),'/extensions/LinuxDockerExtension')]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "VMAccessForLinux",
|
||||
"typeHandlerVersion": "1.4",
|
||||
"autoUpgradeMinorVersion": "true",
|
||||
"settings": {},
|
||||
"protectedSettings": {
|
||||
"username": "[parameters('adminUsername')]",
|
||||
"password": "[parameters('adminPassword')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
Двоичные данные
deploy/azurestack/instances/ubuntu_server_1604_base/Canonical.UbuntuServer.1.0.0/Icons/Hero.png
Normal file
После Ширина: | Высота: | Размер: 90 KiB |
Двоичные данные
deploy/azurestack/instances/ubuntu_server_1604_base/Canonical.UbuntuServer.1.0.0/Icons/Large.png
Normal file
После Ширина: | Высота: | Размер: 5.3 KiB |
Двоичные данные
deploy/azurestack/instances/ubuntu_server_1604_base/Canonical.UbuntuServer.1.0.0/Icons/Medium.png
Normal file
После Ширина: | Высота: | Размер: 4.3 KiB |
Двоичные данные
deploy/azurestack/instances/ubuntu_server_1604_base/Canonical.UbuntuServer.1.0.0/Icons/Small.png
Normal file
После Ширина: | Высота: | Размер: 1.6 KiB |