Quickstart for Cloud DNS#

Rackspace offers a flexible and scalable solution to DNS management through its Cloud DNS service.

Concepts#

To use this service effectively, you should understand how these key ideas are used in this context:

domain

An entity containing all DNS-related information.

zone

A single manager’s scope of control within the domain name space.

Authentication#

To use this service you have to authenticate first. To do this, you will need your Rackspace username and API key. Your username is the one you use to login to the Cloud Control Panel at http://mycloud.rackspace.com/.

To find your API key, use the instructions in View and reset your API key.

You can specify a default region. Here is a list of available regions:

  • DFW (Dallas-Fort Worth, TX, US)

  • HKG (Hong Kong, China)

  • IAD (Blacksburg, VA, US)

  • LON (London, England)

  • SYD (Sydney, Australia)

Some users have access to another region in ORD (Chicago, IL). New users will not have this region.

Once you have these pieces of information, you can pass them into the SDK by replacing {username}, {apiKey}, and {region} with your info:

CloudIdentity cloudIdentity = new CloudIdentity()
{
    APIKey = "{apiKey}",
    Username = "{username}"
};
CloudIdentityProvider cloudIdentityProvider = new CloudIdentityProvider(cloudIdentity);
UserAccess userAccess = cloudIdentityProvider.Authenticate(cloudIdentity);
CloudDnsProvider cloudDNSProvider = new CloudDnsProvider(
  cloudIdentity,
  "{region}",
  true,
  null
);
// Not currently supported by this SDK
// Authentication in jclouds is lazy and happens on the first call to the cloud.
CloudDNSApi cloudDNSApi = ContextBuilder.newBuilder("rackspace-clouddns-us")
    .credentials("{username}", "{apiKey}")
    .buildApi(CloudDNSApi.class);
pkgcloud = require('pkgcloud');
var rackspace = pkgcloud.dns.createClient({
  provider: 'rackspace',
  username: '{username}',
  apiKey: '{apiKey}'
});
require 'vendor/autoload.php';

use OpenCloud\Rackspace;

$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
    'username' => '{username}',
    'apiKey'   => '{apiKey}'
));
import pyrax

pyrax.set_setting('identity_type', 'rackspace')
pyrax.set_credentials('{username}', '{apiKey}')
require 'fog'

@client = Fog::DNS.new(
  :provider => 'rackspace',
  :rackspace_username => '{username}',
  :rackspace_api_key => '{apiKey}'
)
# {username}, {apiKey} below are placeholders, do not enclose '{}' when you replace them with actual credentials.

curl -s -X POST https://identity.api.rackspacecloud.com/v2.0/tokens \
  -H "Content-Type: application/json" \
  -d '{
    "auth": {
      "RAX-KSKEY:apiKeyCredentials": {
        "username": "{username}",
        "apiKey": "{apiKey}"
      }
    }
  }' | python -m json.tool

# From the resulting json, set two environment variables: TOKEN and ENDPOINT.

export TOKEN="{tokenId}"
export ENDPOINT="{publicUrl}" # For the Cloud DNS service

Use the API#

Some of the basic operations you can perform with this API are described below.

Zones#

You can perform create, read, update, and delete operations on zones. A few of our SDKs use ‘domain’ to refer to the top-level entity of a DNS entry.

Create zone#

The first step in managing your domains and subdomains is to create a DNS zone, which you can think of as being the “root” level. So, for example, if you have a domain called example.com, create a zone called example.com via the DNS service as follows:

DnsConfiguration dnsConfiguration = new DnsConfiguration(
    new DnsDomainConfiguration(
        name: "domain.com",
        timeToLive: default(TimeSpan?),
        emailAddress: "admin@domain.com",
        comment: "Root level for domain.com",
        records: new DnsDomainRecordConfiguration[] { },
        subdomains: new DnsSubdomainConfiguration[] { }));
DnsJob<DnsDomains> createResponse =
      await cloudDnsProvider.CreateDomainsAsync(
              dnsConfiguration,
              AsyncCompletionOption.RequestCompleted,
              CancellationToken.None, null);
// Not currently supported by this SDK
DomainApi domainApi = cloudDNSApi.getDomainApi();

List<CreateDomain> createDomains = Lists.newArrayList();
CreateDomain createDomain = CreateDomain.builder()
        .name(DOMAIN)
        .email("admin@domain.com")
        .ttl(300)
        .build();

createDomains.add(createDomain);

Set<Domain> domains = awaitComplete(cloudDNSApi, domainApi.create(createDomains));
var details = {
  name: 'example.com',
  email: 'admin@example.com',
  ttl: 300,
  comment: 'Root level for example.com'
};

rackspace.createZone(details, function (err, zone) {
  if (err) {
    // TODO handle appropriately
    return;
  }

  // TODO use the created zone
});
$dnsService = $client->dnsService();

$domain = $dnsService->domain();
$domain->create(array(
    'name'         => 'example.com',
    'emailAddress' => 'admin@example.com',
    'ttl'          => 300,
    'comment'      => 'Root level for example.com'
));
domain = pyrax.cloud_dns.create(name="example.com",
                             emailAddress="admin@example.com",
                             ttl=300)
zone = @client.zones.create(
  :domain => 'example.com',
  :email => 'admin@example.com',
  :ttl => 300,
  :comment => 'Root level for example.com'
)
curl -X POST $ENDPOINT/domains \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
      "domains" : [ {
          "name" : "example.com",
          "comment" : "Root level for example.com",
          "subdomains" : {
              "domains" : []
          },
          "ttl" : 300,
          "emailAddress" : "admin@example.com"
      } ]
  }' | python -m json.tool

Get zone#

After you create a zone, you can retrieve it and inspect its details as follows:

Task<Tuple<ReadOnlyCollectionPage<DnsDomain>,int?>> domainsList =
      cloudDNSProvider.ListDomainsAsync("domain.com", null, null, CancellationToken.None);
Tuple<ReadOnlyCollectionPage<DnsDomain>,int?> x = await domainsList;
// Not currently supported by this SDK
DomainApi domainApi = cloudDNSApi.getDomainApi();

Domain domain = domainApi.get({domainId});
rackspace.getZones({ name: 'example.com' }, function (err, zones) {
  if (err) {
    console.dir(err);
    return;
  }

  // TODO use the zones.
});
$dnsService = $client->dnsService();

// First define your domain's ID
$domainId = '{domainId}';

// Alternatively, if you do not know your domain ID:
$domains = $dnsService->domainList(array(
    'name' => 'example.com'
));

foreach ($domains as $domain) {
    $domainId = $domain->id;
    break;
}

// Now, to get the full domain object:
$domain = $dnsService->domain($domainId);
domain = pyrax.cloud_dns.find(name="example.com")
zone = service.zones.all.find { |z| z.name == 'example.com' }
curl -X GET $ENDPOINT/domains/{domainId} \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" | python -m json.tool

Modify zone#

You can modify your DNS zone to change any of the details other than the zone name, so long as the new values are valid. For example, you can change the zone’s email address, but the new address must follow the correct email address format; you can define a new TTL, but the new TTL must be > 300s. However, the zone name cannot be changed. If you need to modify the zone name, delete the zone (explained below) and create another zone with the new domain.

DnsUpdateConfiguration dnsUpdateConfiguration =
      new DnsUpdateConfiguration(
        new DnsDomainUpdateConfiguration(
              {domain},
              comment: "domain updated"));
await cloudDNSProvider.UpdateDomainsAsync(
      dnsUpdateConfiguration,
      AsyncCompletionOption.RequestCompleted,
      CancellationToken.None,null);
// Not currently supported by this SDK
DomainApi domainApi = cloudDNSApi.getDomainApi();

UpdateDomain updateDomain = UpdateDomain.builder()
        .email("changed@domain.com")
        .ttl(3600)
        .build();

awaitComplete(cloudDNSApi, domainApi.update({domainId}, updateDomain));
myZone.emailAddress = 'changed@example.com';
rackspace.updateZone(myZone, function (err) {
  if (err) {
    console.dir(err);
    return;
  }

  // TODO The zone was successfully modified.
});
// Specify your changes
$changes = array(
    'email' => 'changed@example.com',
    'ttl'   => 3600
);

$domain->update($changes);
domain.update(emailAddress="changed@example.com")
zone.email = 'changed@example.com'
zone.ttl = 3600
zone.save
curl -X PUT -d \
  '{
      "comment" : "{updatedComment}",
      "ttl" : 300,
      "emailAddress" : "{updatedEMailAddress}"
  }' \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  $ENDPOINT/domains | python -m json.tool

Delete zone#

To delete a DNS zone:

DomainId[] domainIds = new DomainId[1];
DnsJob deleteResponse = await cloudDNSProvider.RemoveDomainsAsync(
  domainIds,
  false,
  AsyncCompletionOption.RequestCompleted,
  CancellationToken.None,
  null
);
// Not currently supported by this SDK
DomainApi domainApi = cloudDNSApi.getDomainApi();

awaitComplete(cloudDNSApi, domainApi.delete({domainIds}, true));
rackspace.deleteZone(myZone, function (err) {
  if (err) {
    console.dir(err);
    return;
  }
  console.log('Zone successfully deleted.');
});
$domain->delete();
domain.delete()
zone.destroy
curl -X DELETE $ENDPOINT/domains/{domainId} \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" | python -m json.tool

WARNING: deleting a zone will also delete all the records within it. Please use with care.

Records#

You can perform create, read, update, and delete operations on records.

Create record#

After you create a zone, you will normally add at least one record to it so that it will be useful. For example, an A record gives the IP address of the domain or a subdomain, while a CNAME creates an alias (a canonical name) to another record.

To create a DNS zone record:

DomainId domainId = new DomainId("{domainId}");
DnsDomainRecordConfiguration[] recordConfigurations =
        {
            new DnsDomainRecordConfiguration(
                type: DnsRecordType.A,
                name: string.Format("www.{0}", {domainName}),
                data: "{data}",
                timeToLive: null,
                comment: "{comment}",
                priority: null)
        };
DnsJob<DnsRecordsList> recordsResponse =
      await cloudDNSProvider.AddRecordsAsync(
              domainId,
              recordConfigurations,
              AsyncCompletionOption.RequestCompleted,
              CancellationToken.None, null);
DnsRecord[] records = recordsResponse.Response.Records.ToArray();
// Not currently supported by this SDK
RecordApi recordApi = cloudDNSApi.getRecordApi({domainId});

Record createARecord = Record.builder()
        .type("A")
        .name("app.domain.com")
        .data("192.168.1.1")
        .ttl(3600)
        .build();

List<Record> createRecords = ImmutableList.of(createARecord);

Set<RecordDetail> records = awaitComplete(cloudDNSApi, recordApi.create(createRecords));
var recDetails = {
  name: 'app.example.com',
  data: '192.168.1.1',
  type: 'A'
};

rackspace.createRecord(myZone, recDetails, function (err, rec) {
  if (err) {
    console.dir(err);
    return;
  }
  console.log('Record ' + rec.name + ' was successfully created.');
});
// Add an A record
$record = $domain->record(array(
    'type' => 'A',
    'name' => 'app.example.com',
    'ttl'  => 3600,
    'data' => '192.168.1.1'
));

$record->create();
domain.add_record({'type': 'A',
                   'name': 'app.example.com',
                   'ttl': 3600,
                   'data': '192.168.1.1'})
record = zone.records.create(
  :type => 'A',
  :name => 'app.example.com',
  :ttl => 3600,
  :value => '192.168.1.1'
)
curl -s -X POST $ENDPOINT/domains/{domainId}/records \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
      "records": [
          {
              "name" : "app.example.com",
              "type" : "A",
              "data" : "192.168.1.1",
              "ttl" : 3600
          }
      ]
  }' | python -m json.tool

Get record#

If the zone has one or more records, you can retrieve them for inspection or manipulation as follows:

DomainId domainId = new DomainId("{domainId}");
Task<ReadOnlyCollection<DnsRecord>> recordsList =
      (await cloudDNSProvider.ListRecordsAsync(
              domainId,
              DnsRecordType.Mx,
              null,
              null,
              null,
              null,
              CancellationToken.None)).Item1.GetAllPagesAsync(CancellationToken.None, null);
// Not currently supported by this SDK
RecordApi recordApi = cloudDNSApi.getRecordApi({domainId}});

RecordDetail record = recordApi.get({recordId}});
rackspace.getRecord(myZone, '{recordId}', function (err, rec) {
  if (err) {
    console.dir(err);
    return;
  }
  console.log('Record ' + rec.name + ' was successfully retrieved.');
});
// First define your record's ID
$recordId = '{recordId}';

// Alternatively, if you do not know your record ID:
$records = $domain->recordList(array(
    'name' => 'imap.example.com',
    'type' => 'MX'
));

foreach ($records as $record) {
    $recordId = $record->id;
    break;
}

// Now, to get the full record object:
$record = $domain->record($recordId);
record = domain.get_record('{recordId}')
record = my_zone.records.get('{recordId}')
curl -X GET $ENDPOINT/domains/{domainId}/records/{recordId} \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" | python -m json.tool

Update record#

To modify a DNS record:

DomainId domainId = new DomainId("{domain_id}");
DnsDomainRecordUpdateConfiguration recordUpdateConfiguration =
      new DnsDomainRecordUpdateConfiguration(
        {records}[0],
        {records}[0].Name,
        comment: "{comment}");
await cloudDNSProvider.UpdateRecordsAsync(
      domainId,
      new[] { recordUpdateConfiguration },
      AsyncCompletionOption.RequestCompleted,
      CancellationToken.None, null);
DnsRecord updatedRecord =
      await cloudDNSProvider.ListRecordDetailsAsync(
              domainId,
              {records}[0].Id,
              CancellationToken.None);
// Not currently supported by this SDK
RecordApi recordApi = cloudDNSApi.getRecordApi({domainId}});

Record updateRecord = Record.builder()
        .data("192.168.1.2")
        .build();

awaitComplete(cloudDNSApi, recordApi.update("{recordId}", updateRecord));
myRec.data = '192.168.1.2';
rackspace.updateRecord(myZone, myRec, function (err){
  if (err) {
    console.dir(err);
    return;
  }

  // The record was successfully modified.
});
// Let's decrease its TTL by an hour:
$record->ttl -= 60;

// And change its data value:
$record->data = '192.168.1.2';

$record->update();
record.update(data="192.168.1.2")
# Let's decrease its TTL by an hour:
record.ttl -= 60

# And change its data value:
record.value = '192.168.1.2'

record.save
curl -X PUT $ENDPOINT/domains/{domainId}/records/{recordId} \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type" : "A",
    "data" : "192.168.1.2",
    "ttl" : 3600
  }' | python -m json.tool

Delete record#

To delete a DNS record:

DomainId domainId = new DomainId("{domain_id}");
await cloudDNSProvider.RemoveRecordsAsync(
      domainId,
      new[] { {records}[0].Id },
      AsyncCompletionOption.RequestCompleted,
      CancellationToken.None, null);
RecordApi recordApi = cloudDNSApi.getRecordApi({domainId});

awaitComplete(cloudDNSApi, recordApi.delete({recordIds}));
// Not currently supported by this SDK
rackspace.deleteRecord(myZone, myRec, function (err) {
  if (err) {
    console.dir(err);
    return;
  }

  // The DNS record was successfully deleted.
});
$record->delete();
record.delete()
record.destroy
curl -X DELETE $ENDPOINT/domains/{domainId}/records/{recordId} \
  -H "X-Auth-Token: $TOKEN" \
  -H "Content-Type: application/json" | python -m json.tool

More information#

This quickstart is intentionally brief, demonstrating only a few basic operations. To learn more about interacting with Rackspace cloud services, explore the following sites: