How to add a Certificate to an azure service fabric cluster vmset - azure-service-fabric

I have a Service Fabric cluster with a vmset based on a key-vault for its secrets. It runs fine, but now I need to add a certificate to the personal stores on the running instances (by preference without doing it manually in RDP). I used powershell to add the certificate to the key-vault, but even after increasing the capacity of vmset the new vm does not has the new certificate.
When I try to "reimage" the existing vm's I get the error
Failed to reimage virtual machine instance 'xxxxxxx'. Error: Virtual
Machine Scale Sets with extension
Microsoft.Azure.ServiceFabric.ServiceFabricNode cannot be reimaged.
So I though I could update the certificate on a virtual machine with the following command
$vm = Add-AzureVMSecret -VM $vm -SourceVaultId $SourceVaultId -CertificateStore $certStore -CertificateUrl $certUrl;
Update-AzureRmVM -ResourceGroupName $resourceGroup -VM $vm
But it seems I'm unable to get an individual vm inside the vmset.
$vm = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name "xxxxxx"
Get-AzureRmVM : The Resource
'Microsoft.Compute/virtualMachines/xxxxxx' under resource group
'xxxxxxxxxxxxxxx' was not found. StatusCode: 404 ReasonPhrase: Not
Found
Does anyone know how to add a certificate on existing vm's inside a vmset?
And what if I need to update an certificate that is going to expire, seems like I'll need to do something simular.

You can define the certificates to deploy in the ARM template.
Examples here and here.
Relevant node: 'osProfile'.

Related

Removing Cluster Resource Dependency: SQL Server Failover Cluster

I want to remove a disk Cluster Dependency. I wanted to remove a Cluster Disk resources from a SQL Server Engine Service and add it later into the Cluster.
The script I am using is:
$DiskResources = #("Cluster Disk 1,.....")
foreach($resource in $DiskResources)
{
Remove-ClusterResourceDependency -Resource $Resource -Provider ??????
Write-Host "Removed Cluster Disk Resource " $resource
}
What is the -Provider parameter I should use?
The examples I saw in BOL uses IP address. I don't see IP address for the Cluster Disks.
I got the answer. The script should be like:
$DiskResources = #("Cluster Disk 1,.....")
foreach($resource in $DiskResources)
{
Remove-ClusterResourceDependency -Resource "SQL Server (xxxxx)" -Provider $resource
Write-Host "Removed Cluster Disk Resource " $resource
}

Issue with service fabric resource manager file deployment (apim.json and apim.parameters)

My requirement is as follows:
I have an web API whose port I have removed from the ServiceManifest.xml file. This is done so that I can implement multiple node multiple calls feature from API management. (i.e. I want to remove dependency on port number)
While deploying API management resource files, I am facing issues while deploying apim.json and apim.parameters.json file.
Following is the exception I am getting always.
"Service activation failed. Please look at the details in Activity Log on the left side. In case you are deploying into VNET please make sure prerequisites are followed as described on https://aka.ms/apiminvnet"
There is nothing in the log files when I am uploading.
I am using following link for the deployment and testing. https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-tutorial-deploy-api-management
I am getting exception in running powershell script
New-AzureRmResourceGroupDeployment -ResourceGroupName $groupname -TemplateFile "$templatepath\apim.json" -TemplateParameterFile "$templatepath\apim.parameters.json" -Verbose

Associate a Public IP in an Azure Resource Group to a Web App?

I'm playing around with Azure Resource Groups.
I've created a group, and in it, I've created a web app. (This is all just academic and I'll delete it all when I'm done leaning, so I don't mind sharing the data.) The web app is located at http://woodswild.azurewebsites.net, and indeed you can go to that address and it will resolve (although there is nothing there, which is fine for now.)
Then, in the same resource group, I also created a Public IP Address that is static.
That all looks good (I think, anyway). But in the Portal UI, I see that this IP is not associated to anything:
Aaannndd.... I'm having a hard time figuring out how to do that. I created the Public IP from within Azure PowerShell with this command:
New-AzureRmPublicIpAddress -AllocationMethod Static -ResourceGroupName TestRG1 -ReverseFqdn woodswild.centralus.cloudapp.azure.com -Name woodswild.azurewebsites.net -Location "Central US" -DomainNameLabel woodswild
According to this article that explains the New-AzureRmPublicIpAddress command, there is no parameter to declare an association. I'm not seeing a way to do it in the Portal UI, and I can't find any answers via Google.
What I'm hoping / wondering / assuming is that once this association is made, you could put the IP Address in a browser and it would resolve to the same place as http://woodswild.azurewebsites.net.
Any ideas? Thanks!!
It is not actually possible to assign a static IP address to a Web App. This is because the IP address used by Web Apps isn't used exclusively by you, but instead it is the frontend address pool of the load balancers that sit in front of Azure's Web App service.
However Microsoft do assert that any web app that can have a domain name assigned will keep its external incoming address, and external outgoing addresses for the lifetime of the Web App. This applies to Basic, Standard and Premium SKU. (it might apply to Shared too - I'll have to dig out the doc)
You can find your external incoming IP Address with (yeah, basically, ping it and see what DNS gives!)
Resolve-DnsName (Get-AzureRmWebApp `
-ResourceGroupName $ResourceGroupName -Name $Name).EnabledHostNames[0]
and your external outgoing IP Addresses with
(Get-AzureRmWebApp -ResourceGroupName $ResourceGroupName `
-Name $Name).OutboundIpAddresses
It seems I fell at the first hurdle here, and didn't actually read the question. Or at least my brain seems to have read different words than the ones that are there! (I'll leave the wrong answer here because a, it might be useful to someone, b, I'll likely paste it into an actual answer that it fits one day)
The reason this is so confusing is that it is not instantly obvious the process that Azure uses to update resources.
For the majority of existing resource changes that are made in Azure, the process goes something like
Get-something, assign it to a variable.
Change a property of that variable, by assigning some other value.
Write the change to Azure using the Set-something cmdlet.
In the case of assigning an IP address to a VM, this is the code to use
$ipaddr = New-AzureRmPublicIpAddress -Name test1 `
-ResourceGroupName win10 `
-Location westeurope `
-AllocationMethod Static
$nic = Get-AzureRmNetworkInterface -Name $name `
-ResourceGroupName $ResourceGroupName #1
$nic.IpConfigurations[0].PublicIpAddress = $ipaddr #2
Set-AzureRmNetworkInterface -NetworkInterface $nic #3

Jenkins: dynamically connect slave to master without knowing node secret

I struggle to (dynamically) start the Jenkins slave agent from my dedicated slave machine (Windows 2012 R2 server).
The Jenkins master (ver. 1.617 - which I can upgrade if necessary, but not downgrade [before ver. 1.498 no credentials were required]) is on a Windows 2012 R2 server.
Security is enabled and configured via the Active Directory plugin and Project-based Matrix Authorization Strategy.
Because of the Active Directory involved, I cannot simply add a system user to authenticate with (via -jnlpCredentials username:password or -jnlpCredentials username:apitoken). As a workaround I am using my Jenkins service user for that, but I don't like it's API-Token lying around hard-coded in the script.
I am trying to use the alternative -secret secretKey, but that secretKey is randomly created when a slave node is registered on the master.
Since I am using the Azure Slave Plugin, the slave nodes and the associated virtual machines are created for me.
The virtual machines are created from a pre-defined image, that I can change in whatever way necessary.
In this pre-defined image I have a PowerShell script executed on start-up. It is derived from the sample given here. It doesn't have to be PowerShell, any other way would be okay as well.
Set-ExecutionPolicy Unrestricted
# base url to Jenkins master
$jenkinsserverurl = "https://jenkins.mycompany.com/"
# the azure-slave-plugin is creating VMs with names like 'Azure0807150842'
$vmname = (Get-Culture).TextInfo.ToTitleCase($env:computername.tolower())
# authenticate with Jenkins service user + API-token - since we don't know the '-secret'
$apiToken="jenkins_user:1234abcdefab56c7d890de1f2a345b67"
Write-Output "Downloading jenkins slave jar "
# in order to avoid updating it manually for Jenkins master updates
$slaveJarSource = $jenkinsserverurl + "jnlpJars/slave.jar"
$slaveJarLocal = "C:\jenkins_home\slave.jar"
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($slaveJarSource, $slaveJarLocal)
Write-Output "Executing slave process "
$jnlpSource = $jenkinsserverurl+"computer/" + $vmname + "/slave-agent.jnlp"
# expect java.exe in the PATH, and use -noCertificateCheck to skip SSL validation
& java -jar $slaveJarLocal -jnlpCredentials $apiToken -jnlpUrl $jnlpSource -noCertificateCheck
Downloading the JNLP file and reading the contained secret is no option, since I need proper HTTP authentication at the Jenkins master for that as well.
Write-Output "Downloading jenkins slave jnlp "
$jnlpSource = $jenkinsserverurl+"computer/" + $vmname + "/slave-agent.jnlp"
$jnlpLocal = "C:\jenkins_home\slave-agent.jnlp"
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($jnlpSource, $jnlpLocal)
Write-Output "Extracting secret from jenkins slave jnlp "
[xml]$jnlpFile = Get-Content $jnlpLocal
# the first argument in the generated JNLP contains the secret
$secret = Select-Xml "//jnlp/application-desc/argument[1]/text()" $jnlpFile
How can I get my hands on the generated secret (without disabling the security), or
What kind of credentials can I use instead (without using an actual user - such as my own or the Jenkins service user)?
In an ideal world, the plugin creating the slave node and its VM, would login to the created VM and execute a script similar to the one in my question - with the addition of the injected Jenkins server url, VM name, and generated secret. Since that is not the case for the current Azure Slave Plugin version, I am stuck with my workaround script - using my existing Jenkins service user.
I use this to let the plugin create a bigger/faster VM on the fly, which is only used for a daily test run and is shutdown automatically the rest of the time (and therefore causes no costs when unused).
If someone is interested, that is the setup I ended up with:
Generalized Azure VM Image (Windows 2012 R2, with JDK, Maven, Git
installed). Via NSSM, I installed the PowerShell script (which
starts the slave agent) as a Windows Service, to be executed
automatically at machine bootup (same as in the question):
Set-ExecutionPolicy Unrestricted
# base url to Jenkins master
$jenkinsserverurl = "https://jenkins.mycompany.com/"
# the azure-slave-plugin is creating VMs with names like 'Azure0807150842'
$vmname = (Get-Culture).TextInfo.ToTitleCase($env:computername.tolower())
# authenticate with Jenkins service user + API-token - since we don't know the '-secret'
$apiToken="jenkins_user:1234abcdefab56c7d890de1f2a345b67"
Write-Output "Downloading jenkins slave jar "
# in order to avoid updating it manually for Jenkins master updates
$slaveJarSource = $jenkinsserverurl + "jnlpJars/slave.jar"
$slaveJarLocal = "C:\jenkins_home\slave.jar"
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($slaveJarSource, $slaveJarLocal)
Write-Output "Executing slave process "
$jnlpSource = $jenkinsserverurl+"computer/" + $vmname + "/slave-agent.jnlp"
# expect java.exe in the PATH, and use -noCertificateCheck to skip SSL validation
& java -jar $slaveJarLocal -jnlpCredentials $apiToken -jnlpUrl $jnlpSource -noCertificateCheck
Jenkins master with Azure Slave Plugin installed and configured to
use this VM image, with shutdown-on-idle after five minutes.
Jenkins Maven Project (Job) that is configured to only run on a
Azure slave node, checks out my test project from Git, and executes
the jUnit Selenium tests from there.
I've hit the same issue with the Jenkins Openstack plugin.
It seems that they will inject the secret directly in the machine's metadata.
https://github.com/jenkinsci/openstack-cloud-plugin/issues/104
In the meanwhile, I'll use instead the SSH slave, more secure since only the pub key needs to be deployed in the slave.

Update Windows Azure Endpoint with load balancer probe settings

I am trying to update the probe settings for a load balanced endpoint in windows azure but facing
"Update-AzureVM : Failed: The server encountered an internal error. Please retry the request."
Since probe settings for endpoints are not accessible through the web GUI I am using the PowerShell cmdlets to achieve this. I have followed the guide here
http://www.windowsazure.com/en-us/manage/windows/common-tasks/how-to-load-balance-virtual-machines/#lbprobes
I have also tried with adding a new endpoint with cmdlet Add-AzureEndpoint and updating a existing endpoint with Set-AzureEndpoint. The commands executed is:
Get-AzureVM -Name "web-server-01" -ServiceName "web-servers" | Add-AzureEndpoint -LBSetName "Web_80" -Name "Web" -Protocol "tcp" -LocalPort 80 -PublicPort 80 -ProbePort 80 -ProbePath "/ping" -ProbeProtocol http | Update-AzureVM
Is there anyone familiar with the problem and has succeeded updating the probe settings or knows how to get more out of the error message generated?
I faced a similar problem when I try to get the endpoints for a VM using:
Get-AzureVM –ServiceName “XXX” –Name “XXX” | Get-AzureEndpoint
Setting the default subscription bevore retrieving the VM solved it:
Set-AzureSubscription -DefaultSubscription XXX
Maybe that helps you too