0

I've two private hosted zones created for populating A records and PTR records corresponding to my EC2 instance's private ip. Yes, it's the private ip that I need. This subnet is routed to our corporate data center, so we need non-cryptic hostnames and consistent reverse lookup on them within the account.

I've got the forward lookup working well, however I'm confused how exactly it should be for the reverse lookup on the IP. Assume, my CIDR is 192.168.10.0/24 where the EC2 instances will get created.

    const fwdZone = new aws_route53.PrivateHostedZone(
      this, "myFwdZone", {
        zoneName: "example.com",
        vpc: myVpc,
    });

    const revZone = new aws_route53.PrivateHostedZone(
      this, "myRevZone", {
        zoneName: "10.168.192.in-addr.arpa",
        vpc: myVpc,
      }
    );

I'm later creating the A record by referencing the EC2 instance's privateIp property. This worked well.

    const myEc2 = new aws_ec2.Instance(this, 'myEC2', {...})

    new aws_route53.RecordSet(this, "fwdRecord", {
      zone: fwdZone,
      recordName: "myec2.example.com",
      recordType: aws_route53.RecordType.A,
      target: aws_route53.RecordTarget.fromIpAddresses(
        myEc2.instancePrivateIp
      ),
    });

However, when I try to create the PTR record for the same, I've got some trouble. I needed to extract the fourth octet and specify as the recordName

    new aws_route53.RecordSet(this, "revRecord", {
      zone: revZone,
      recordName: myEc2.instancePrivateIp.split('.')[3],
      recordType: aws_route53.RecordType.PTR,
      target: aws_route53.RecordTarget.fromValues("myec2.example.com"),
    });

The CDK synthesized CloudFormation template looks odd as well, especially the token syntax.

  revRecordDEADBEEF:
    Type: AWS::Route53::RecordSet
    Properties:
      Name: ${Token[TOKEN.10.168.192.in-addr.arpa.
      Type: PTR
      HostedZoneId: A12345678B00CDEFGHIJ3
      ResourceRecords:
        - myec2.example.com
      TTL: "1800"

Is this the right way to achieve this ? If I specified the recordName as just the privateIp, then the synthesized template ends up doing something else, which I see is incorrect too.

  revRecordDEADBEEF:
    Type: AWS::Route53::RecordSet
    Properties:
      Name:
        Fn::Join:
          - ""
          - - Fn::GetAtt:
                - myEC2123A01BC
                - PrivateIp
            - .10.168.192.in-addr.arpa.
      Type: PTR
      HostedZoneId: A12345678B00CDEFGHIJ3
      ResourceRecords:
        - myec2.example.com
      TTL: "1800"
Roby
  • 23
  • 4
  • The private IP is a token that is resolved during deployment, so you cannot perform string manipulation on it in your CDK code. Try Cfn functions instead: `recordName: Fn.select(0, Fn.split('.', myEc2.instancePrivateIp))`. Let me know if this works and I'll add it as an answer. – gshpychka Aug 22 '22 at 14:34
  • I was attempting the same meanwhile and updated my question. Thank you for the explanation on why it works, I didn't know that previously on why it broke and why my next attempt using `Fn` worked. However my reverse resolution is still broken. That's because I think the cdk recordset appends the domain name (the PTR one) to the `recordName` ? – Roby Aug 22 '22 at 14:48
  • Perhaps this will be helpful: https://aws.amazon.com/premiumsupport/knowledge-center/route-53-reverse-dns/ – gshpychka Aug 22 '22 at 15:42
  • @gshpychka Your answer is correct. I overlooked the ordering of octet. I should have selected the last octet since I'm selecting from IP address itself. I will correct my question accordingly. You can mark your reply as the answer. Just that the select index has to be 3 – Roby Aug 22 '22 at 15:51

1 Answers1

2

Answering the CDK part of your question: the original error was because you were performing string manipulation on an unresolved token. Your CDK code runs before any resources are provisioned. This has to be the case, since it generates the CloudFormation template that will be submitted to CloudFormation to provision the resources. So when the code runs, the instance does not exist, and its IP address is not knowable.

CDK still allows you to access unresolved properties, returning a Token instead. You can pass this token around and it will be resolved to the actual value during deployment.

To perform string manipulation on a token, you can use CloudFormation's bult-in functions, since they run during deployment, after the token has been resolved.

Here's what it would look like:

recordName: Fn.select(0, Fn.split('.', myEc2.instancePrivateIp))

As you found out yourself, you were also selecting the wrong octet of the IP address, so the actual solution would include replacing 0 with 3 in the call.

References:

https://docs.aws.amazon.com/cdk/v2/guide/tokens.html

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#intrinsic-functions-and-condition-expressions

gshpychka
  • 8,523
  • 1
  • 11
  • 31