Azure REST API: Network Security Group / Network Interface - rest

I am trying to build a proof-of-concept integration with Azure Cloud into another system. I am not an Azure subject matter expert, so I am struggling with the end-to-end integration.
I am having trouble associating a "Network Security Group" to the "Network Interface". I am able to create both, but they do not not associate to each other until I manually go into the Cloud Portal and associate.
I am using the following:
API Documentation:
https://learn.microsoft.com/en-us/rest/api/compute/virtualmachines
API Explorer:
https://resources.azure.com
I am calling the following end-points in order:
publicIPAddresses
https://management.azure.com/subscriptions/{subscriptionID}/resourceGroups/{resourceGroup}/providers/Microsoft.Network/publicIPAddresses/{resourceName}?api-version=2018-07-01
networkInterfaces
https://management.azure.com/subscriptions/{subscriptionID}/resourceGroups/{resourceGroup}/providers/Microsoft.Network/networkInterfaces/{resourceName}?api-version=2018-07-01
networkSecurityGroups
https://management.azure.com/subscriptions/{subscriptionID}/resourceGroups/{resourceGroup}/providers/Microsoft.Network/networkSecurityGroups/{resourceName}?api-version=2018-07-01
virtualMachines : https://management.azure.com/subscriptions/{subscriptionID}/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachines/{resourceName}?$expand=instanceView&api-version=2018-06-01
Everything else works except the NSG associating to the NIC.
Within the "networkSecurityGroups" message, I pass in the following parameter under the properties node.
"networkInterfaces": [{
"id": "/subscriptions/" + subscriptionID + "/resourceGroups/" + resourceGroup + "/providers/Microsoft.Network/networkInterfaces/" + networkInterfaces
}
]
I've tried reversing it by referencing the NSG in the Interface REST call, but still doesn't work. Oddly enough, I use the same syntax to associate the Interface to the VM itself, and that works as expected. Variations of the same syntax work with associating the PublicIP to the Interface, disks to VM, ect.
Any thoughts?

pretty sure you need to add this under NIC properties section:
"networkSecurityGroup": {
"id": "NSG_Resource_Id"
}

Related

Azure DevOps IP addresses

I have an application running on Web App that needs to communicate with Azure DevOps Microsoft hosted agent. I've set some IP restrictions to deny everything and now in the process of whitelisting agent's IPs. When I read this page it refers to weekly json that contains objects about everything what I need (CIDRs per region). I've parsed the json, added them to my allow list, however the agent's public IP address is not from the range mentioned in the json. The way I checked it was running bash task on the agent to curl icanhazip.com. Does anyone know if the list is complete or should I look somewhere else?
I.e. example in my case:
I use this data (since my ADO org is in West Europe):
{
"name": "AzureDevOps.WestEurope",
"id": "AzureDevOps.WestEurope",
"properties": {
"changeNumber": 1,
"region": "westeurope",
"regionId": 18,
"platform": "Azure",
"systemService": "AzureDevOps",
"addressPrefixes": [
"40.74.28.0/23"
],
"networkFeatures": null
}
}
but the agent initiates connection from the IP: 20.238.71.171, which is not in any of the CIDRs privided by that json file (checked all other regions with ADO).
Any thoughts / help?
You would need to whitelist ALL ranges from, for instance, Azure West Europe. Those are a lot of different IP ranges, as Azure DevOps hosted agents do not have a service Tag.
Since this opens up your firewall to literally every VM running in West Europe, this is usually not really desired, as it is just a bit short of opening up your App to the entire world.
Hence, what people usually do is the following:
First task in a build job, fetch the public IP address of the executing build agent, using something like ipfy.org
Use AZ CLI to add this IP as a single IP allow rule to your app
Do your deployment etc
Remove the IP rule again
If you mean MS-hosted agent:
You should use AzureCloud service tag
The IP address ranges for the hosted agents are listed in the weekly file under AzureCloud., such as AzureCloud.westus for the West US region.
Docs:
https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml#networking

How can I check if a resource was created by CloudFormation?

I have inherited an AWS account with a lot of resources. Some of them were created manually, other by CloudFormation.
How can I check if a resource (in my case Security Group) was created by CloudFormation and belongs to a stack?
For some security groups aws ec2 describe-security-groups --group-ids real_id results in:
...
"Tags": [
{
"Value": "REAL_NAME",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "arn:aws:cloudformation:<REAL_ID>",
"Key": "aws:cloudformation:stack-id"
},
]
...
Other security groups don't have any tags.
Is it the only indicator? I mean, someone could easily remove tags form an SG created by CloudFormation.
As per the official documentation, in addition to any tags you define, AWS CloudFormation automatically creates the following stack-level tags with the prefix aws::
aws:cloudformation:logical-id
aws:cloudformation:stack-id
aws:cloudformation:stack-name
All stack-level tags, including automatically created tags, are propagated to resources that AWS CloudFormation supports. Currently, tags are not propagated to Amazon EBS volumes that are created from block device mappings.
--
This should be a good place to start with but since CF doesn't enforce the stack state so if someone deleted something manually then you would never know.
If I were you, I would export everything (supported) via Cloudformer and re-design the whole setup my way.
Another way:
You can pass PhysicalResourceId of a resource to describe_stack_resources and get the stack information if it belongs to a CF stack. This is an example:
cf = boto3.client('cloudformation')
cf.describe_stack_resources(PhysicalResourceId="i-0xxxxxxxxxxxxxxxx")
https://boto3.readthedocs.io/en/latest/reference/services/cloudformation.html#CloudFormation.Client.describe_stack_resources
I had the same issue. After no luck finding an answer I made a quick PowerShell script that will just look for a resource name in all of the stacks.
When CF was introduced the stacks didn't tag resources and even now I have issues with CloudFormation reliably tagging resources, there are still times it will tag one resource and not tag another even with the same resource type and in the same stack. In addition some resources like CloudWatch Alarms don't have tags.
$resourceName = "*MyResource*" #Part of the resource name, surrounded by asterisks (*)
$awsProfile = "Dev" #AWS Profile to use
$awsRegion = "us-east-1" #Region to query
Get-CFNStack -ProfileName $awsProfile -Region $awsRegion | Get-CFNStackResourceList -ProfileName $awsProfile -Region $awsRegion | Where-Object {$_.PhysicalResourceId -ilike $resourceName} | Select-Object StackName,PhysicalResourceId

Extending S/4HANA OData service to SCP

I want to extend a custom OData service created in a S/4HANA system. I added a Cloud Connector to my machine, but I don't know how to go from there. The idea is that I want people to access the service from SCP and that I don't need multiple accounts accessing the service on the S/4 system, but just the one coming from SCP. Any ideas?
Ok I feel silly doing this but it seems to work. My test is actually inconclusive because I don't have a cloud connector handy, but it works proxy-ing google.
I'm still thinking about how to make it publicly accessible. There might be people with better answers than this.
create the cloud connector destination.
make a new folder in webide
create file neo-app.json.
content:
{
"routes": [{
"path": "/google",
"target": {
"type": "destination",
"name": "google"
},
"description": "google"
}],
"sendWelcomeFileRedirect": false
}
path is the proxy in your app, so myapp.scp-account/google here. the target name is your destination. I called it just google, you'll put your cloud connector destination.
Deploy.
My test app with destination google going to https://www.google.com came out looking like this. Paths are relative so it doesn't work but google seems proxied.
You'll still have to authenticate etc.

How to Set IP to Static with Powershell and Azure

I have an Azure Dev Test Lab that I am deploying to Azure via Power Shell. I am able to deploy the ARM templates and join to the test domain (not Azure AD) with no issues. The next step I would like to do is to set the IP to static. I can think of 3 ways to possibly do this. Either figure out the IP structure beforehand and deploy it with those settings. Let the DHCP assign the settings and try to problematically set them from Dynamic to Static using Powershell DSC. Or some type of preferred lease from the DHCP. These labs are meant to be stood up and torn down ad hoc. The IPs are internal and not Public. It is possible for me to know the IPs before hand. Could someone make a recommendation on what would make the most sense to pursue?
Well, there are several ways of looking at it, first of all, you can define ip at deployment time, by setting it to static, instead of dynamic:
{
"name": "xxx",
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2016-10-01",
"location": "loc",
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"privateIPAllocationMethod": "Static",
"privateIPAddress": "ipgoeshere",
"subnet": {
"id": "subnetgoeshere"
}
}
}
]
}
but this method is only valid if you know the available IP addresses beforehand and you will have to look those up and pass to the template.
Another way of doing this is créating NIC as dynamic, getting its IP address and setting it to static. All can be done with an ARM Template. The example is a bit too much to paste here, you can check it here. look for deployments called: "[concat(variables('vmNamePrefix'),'setStaticIp')]", and "[concat(variables('vmNamePrefix'),copyIndex(1),'-primaryIp')]", and their corresponding templates: getip and setip
You can do pretty much the same with powershell, I dont have a script Handy, but the logic is the same, deploy > getip > setip

Query on DNS & connect to existing vm

In my current code base, when i create a VM, DNS name is being dynamically set as same as the instance name. For example, consider if my VM name is "anandInstance", DNS name of the name is being generated as "anandInstance.cloudapp.net". Is there a way to change the DNS name like "dns1.cloudapp.net" during the creation thru REST API??
"Connect to existing VM" , is it possible to achieve this option through REST call? In case "connect to existing.." option , we are getting a list of vms/services to choose and VM is getting created successfully. How to achieve the same using API.
Thanks
In my current code base, when i create a VM, DNS name is being
dynamically set as same as the instance name. For example, consider if
my VM name is "anandInstance", DNS name of the name is being generated
as "anandInstance.cloudapp.net". Is there a way to change the DNS name
like "dns1.cloudapp.net" during the creation thru REST API??
I don't think it is possible. Imagine what a nightmare in the portal would become if you were able to do so? How would you link a Cloud Service (whatever.cloudapp.net) to an actual deployment (MyDemoVm123). However you can use your own domain and have CNAME records pointing to your "want-to-change-for-some-reason.cloudapp.net" (frankly I surely think that soon we will use even longer names)
"Connect to existing VM" , is it possible to achieve this option
through REST call?
Connection to a VM is essentially opening a RDP session. If it a windows VM, you can try using the Download RDP file API call. Once you get the file, just start it with "process.start". If it is linux VM, just start SSH client on port 22 (or one you have defined) from the Cloud Service DNS name you have.
UPDATE
From the azure portal,for stand alone machineoption, we are able to give the dns name with deafult cloudoneapp.net. How to do the same
through the rest api call.any specfic paramter is there to specify the
same?
When you are using the REST API, you first create a Cloud Service (still named hosted service in the REST API) where your machine will be hosted. Here you give the name for that hosted service (the dns name with deafult cloudoneapp.net). Then you call the Create Virtual Machine Deployment API action.
In case "connect to existing.." option , we are getting a list of vms/services to choose and VM is getting created successfully. How to
achieve the same using API.
When you want to get list of all VMs, just get a list of all Hosted Services, then get properties of each and make a guess whether it is a VM or a Cloud Service (maybe by querying for Properties of each service). I don't see a direct access to the list of Virtual Machines. But as this feature being PREVIEW, things might change in the future.
Hope my answer is clear?