Accessing the peer roles hostname programmatically - azure

This page describes how to assign host name to role instance through cscfg. How do i access it in my app? The following approach is not working since RoleInstance does not have a VMName member.
foreach (RoleInstance instance in RoleEnvironment.Roles["MyRole"].Instances) {
Console.WriteLine(instance.VMName);
}

When you are inside your Virtual Machine, you can use any .NET API to get the host name in your code i.e.:
Dns.GetHostName();
The reason you may change your Windows Azure VM host name is that in most cases the VM hostname is set as RD00*** so if you have multiple instances all the host names will be different and not easy to remember and manage. So to keep all the host name easy to remember you will use the following property so all instances related to same role will have name as vm-name##, this way you can easily remember the host name and manage them properly.
<Role name="<role-name>" vmName=“<vm-name>”>
So to change hostname you can use above Configuration settings but to get hostname you can just use standard .net API and it will work.

As #AvkashChauhan pointed out, you should be able to retrieve a hostname through the Dns class. I'm curious, though, why you need the hostname. If it's for communication between role instances, you actually don't need the hostname. Rather, you can query the role instance endpoints (assuming you set one up as an internal endpoint), and then for each instance, you can request the ip address and port, which would allow you to establish a direct connection to any given instance. So, modifying the code you had:
foreach (RoleInstance instance in RoleEnvironment.Roles["MyRole"].Instances) {
writeline(InstanceEndpoints["myendpoint"].IPEndpoint);
You may, indeed, need hostname for something, and if so, just ignore this answer. But... if what you're looking for is a way to make tcp/http/udp connections between role instances, this is a pretty simple way to retrieve all the ip/port combinations for your role instances.

Related

Setting internally visible DNS entries on Google cloud

I would like set DNS records visible from instances inside the Google cloud.
For example if I query DNS from my PC I'll get one IP; however if I query DNS from the instance I'll get another IP. (A record to be exact)
Ideally I'd like doing this in most sane/convenient way possible; since I can install caching DNS server on every instance and setup authorative results; and forward caching for the rest (I guess bind9 can do that, never tried it before). But this is configuration sync mess; and it's not elegant. I kinda assume there might exist a better way.
One solution is to use totally different zones for different sets of machines and use the DNS search path to select.
So for example you could set up
server1.internal.yourdomain.com IN A 1.2.3.4
server1.external.yourdomain.com IN A 5.6.7.8
Then set up your machines with resolv.conf containing either
search internal.yourdomain.com
or
search external.yourdomain.com
And then when you lookup server1 on such a machine it will return the address from the appropriate zone. This scheme means you don't need to rely complex routing or IP detection. You will be immune to incidents where internal or external IPs get leaked into each others result.
Of course this does mean that you aren't keeping any IP addresses secret, so make sure you have other security layers in place (you probably shouldn't rely on secret IPs for security anyway)
Assuming you want your VM instances to be able to query other instances by name, and retrieve the desired instance’s private IP, this is already baked into GCP.
Google Cloud Platform (GCP) Virtual Private Cloud (VPC) networks have an internal DNS service that allows you to use instance names instead of instance IP addresses to refer to Compute Engine virtual machine (VM) instances.
Each instance has a metadata server that also acts as a DNS resolver for that instance. DNS lookups are performed for instance names. The metadata server itself stores all DNS information for the local network and queries Google's public DNS servers for any addresses outside of the local network.
[snip]
An internal fully qualified domain name (FQDN) for an instance looks like this:
hostName.c.[PROJECT_ID].internal
You can always connect from one instance to another using this FQDN.
Otherwise, if you want to serve up entirely arbitrary records to a set of machines, you’ll need to serve those records yourself (perhaps using Cloud DNS). In this case, you’d need to reconfigure the resolv.conf file on those instances appropriately (although you can’t just change the file as you see fit). Note that you can't restrict queries to only your own machines, but as David also mentioned, security through obscurity isn't security at all.
Google Cloud DNS Private DNS was just announced to beta and does exactly what you need

How do I restrict RethinkDB access to a specific application?

I have an elastic beanstalk app that uses a rethink-db instance as its database. The obvious thing to do would be to restrict access to the the database to only this application.
But if I set the relevant port in the security group of the Rethinkdb instance to anything other than 0.0.0.0, the application can't reach the DB.
The application is using the private DNS of the database for resolution and is in the same amazon region... as far as I understand, this alone should already get me passt the security group without any rules. Not in this case, apparently.
I have tried adding an exception for the applications security group to the databases security group on that port, as well as the security group of the load balancer of the application. I have also tried both at the same time. No dice.
The beanstalk-app is scalable, so it usually communicates from several instances that can change at a whim. Going over an elastic IP and allowing that in the databases security group is therefore not an option, unfortunately.
In the end, I'm forced to leave the security group of the rethink db on the driver port wide open at 0.0.0.0... Anything else I've tried made it unreachable for my own application.
Can anybody tell me what I'm doing wrong?
as far as I understand, this alone should already get me passt the
security group without any rules
That's not correct. You always have to have a security group rule to allow access. All inbound traffic is blocked by default.
I have tried adding an exception for the applications security group
to the databases security group on that port
That sounds like exactly what you need to do. You need to create an inbound rule in the security group assigned to the database server. In that rule you would specify the ID of the security group that the Elastic Beanstalk instances belong to.
If that isn't working, then you might need to post more information in your question, like the actual security group settings.
Also, you need to make sure your EB instances are trying to connect to the database server via the private IP of the DB server. Your issue sounds like maybe they are using the public IP of the DB server. I know you said they are using the private DNS of the DB server, but you need to make certain that is the case, and make certain that DNS is correctly resolving to the private IP, when referenced from the EB instances.

How to access a site on AWS EC2 without a domain name

I just created a new site on my IIS on Amazon's EC2 and I was wondering if there is a way to access it publicly without assigning a domain.
In detail. I created a new site dev.example.com which is accessible when I am logged in my instance. Is there a way to access it outside by doing let's say 54.xxx.xx.xxx:80:dev.example.com
I don't know if that's even possible so any hints are appreciated
You can definitely do this, but here's what you'll need to do:
Make sure IIS is configured to route any incoming connection on a particular IP address to your site. This is distinct from IIS specifically listening for a particular hostname (e.g. mywebsite.com).
As an alternative to the above, you could also manually set your DNS on your local computer and then use your web browser to visit mywebsite.com. From IIS's perspective, a user will have requested mywebsite.com just as if public DNS were set
As far as the IP address you visit, your instance will either have an ephemeral Public IP Address which will be reset when the instance is stopped and started, or an Elastic IP Address, which persists across restarts.
As #Anthony Manzo mentioned, you'll need to make sure that your Security Group associated with this instance allows Port 80. In addition, you may want to disable Windows Firewall completely (or check that it allows Port 80 on all three "Zones" (Windows Firewall has 3 different zones to manage).
Afaik the IP addresses assigned to EC2 instances can change throughout its lifetime and therefore you should instead generate an Elastic IP Address (which will always direct to your instance). That way, you don't have to deal with DNS yourself and still are always able to connect to your instance.
Have a look at the "Security Groups" on the left hand of your EC2 web console. You'll have to allow TCP 80 (and whatever else) in the Security Group (probably 'default') first.

URL for Specific Azure Web Role Instance

Lets say i have an Azure Web Role with 3 instances. Is there a way for me to directly access each role via a URL change?
Im trying to test the endpoints of the instances individually-- thus my inquiry.
Edit
I am not looking for how to down one of the instances, i'm looking for how to ping an endpoint on each of the instances individually.
Input endpoints are load-balanced, so you can't really direct traffic to one single instance.
Having said that, there are a few workarounds:
There's a health-check event you can set up a handler for. In all but one of your instances, you could set the instance's busy-flag, taking it out of the load balancer. To pull this off, you'd need some type of pub/sub (service bus queue?) mechanism to broadcast messages to the instances, letting them know whether to include or exclude themselves from the load balancer. you'd do something like:
RoleEnvironment.StatusCheck += RoleEnvironment_StatusCheck;
Then...
void RoleEnvironment_StatusCheck(object sender, RoleInstanceStatusCheckEventArgs e)
{
if(someMagicConditionToRemoveFromLB)
e.SetBusy();
}
Another option would be to have something like ARR running in a separate web role instance, providing custom load balancing.
Maybe you could come up with other workarounds, but in general, web/worker load balancing isn't set up for direct-instance access.
To add to what David indicated you can set up InstanceInput endpoints on the roles as well. This creates an endpoint on another port that will send traffic directly to one instance. You can do this and point the local endpoint port to 80 and thus get the ability to address individual instances externally; however, this likely isn't something you want to keep around. You can do this as a test and then remove the endpoints with an in place upgrade that just removed the instanceinput endpoints. Note that during this type of upgrade you may loose connectivity as endpoints are updated.

Liferay and more instances

I have a simple question about Liferay and more instance of it.
I have my Liferay and I can reach it by myhost.com:8080.
Now I would to create an other instance in Liferay Liferay - Portal Instances but I did not understand how I can reach my different instances by browser...
And, How can I configure my different instances about LDAP, CAS... (I would to use the same configuration but if it is not possibile I can copy same configuration for any instances)
A new instance of Liferay contains a whole new set of data, e.g. LDAP etc. If you want to share the same configuration, user database etc., it might be better to just use different sites. This way you don't duplicate the data at all. Also, you can more seamlessly share the same hostname for logging into different sites.
If you want to address a new instance, you'll see that you need a virtual host name for that instance: Your server will need to be accessible through different hostnames. Any time you access the server under the hostname of your new instance (or any site's virtual host that belongs to that instance) you'll be served content from that instance. If you go through the default virtual host, any of the existing sites' virtual hosts, or an unknown virtual host, you'll get to the default instance.
You can do the separate LDAP configuration either through the UI (as you were used to in the first instance) or through portal-ext.properties. The default portal.properties that comes with Liferay should contain a few examples for instance-specific configuration. Note that not all settings can be done instance-specific in portal-ext.properties. Also, you might need to know that the technical name of an instance (e.g. what you find in code and possibly in portal.properties) is "company" - if you ever stumble upon companyId, this is the instance's ID.

Resources