org-formation-cli icon indicating copy to clipboard operation
org-formation-cli copied to clipboard

Subdomains with existing domain

Open CatenaryCloudHQ opened this issue 3 years ago • 0 comments

Subject of the issue

This is such an awesome project! Every time I check amazon's landing page docs or examples, I want to cry :)

So I was looking at the example of subdomains management: https://github.com/org-formation/org-formation-cli/blob/master/examples/templates/subdomains.yml

Everything works nicely, except when the domain's hosted zone (AWS::Route53::HostedZone resource) already exists.

Your environment

  • version of org-foramtion (ofn --version) 0.9.20-beta.3
  • version of node (node --version) v16.13.2
  • which OS/distro Mac

Steps to reproduce

The ofn project is here, it is pretty vanilla: https://github.com/CatenaryCloudHQ/cdk-pipelines-example-org-formation There is subdomains.yml, I haven't committed that task yet. It is included in this issue at the end.

Expected behaviour

(btw behaviour in the issues template is misspelled :)

Expected would be it magically works :)

Actual behaviour

CF in the master account would fail, of course - can't create a duplicate hosted zone or some error like that. I've tried to import zone into CF directly, which kinda worked with some additional effort to disable subdomains and cleanup stacks with delegated zones.

Then I figured why not... skip AWS::Route53::HostedZone? Example below. That worked fine, although I had to add Custom::NullResource to allow an empty stack created for the cases when I'm adding subdomains later.

Would you recommend this approach for existing hosted zones? Can this cause any issues, say when ofn APIs change?

Thanks! Roman

AWSTemplateFormatVersion: '2010-09-09-OC'

# Include file that contains Organization Section.
# The Organization Section describes Accounts, Organizational Units, etc.
Organization: !Include ../organization.yml

# Any Binding that does not explicitly specify a region will default to this.
# Value can be either string or list
DefaultOrganizationBindingRegion: us-east-1

Parameters:

  resourcePrefix:
    Type: String
    Default: catenary

  rootHostedZoneName:
    Type: String

# Section contains a named set of Bindings.
# Bindings determine what resources are deployed where
# These bindings can be !Ref'd from the Resources in the resource section
OrganizationBindings:

  # binding for HostedZone, HostedZoneIdParam, HostedZoneNameParam
  HostedZoneBinding:
    AccountsWithTag: subdomain

  # binding for RootHostedZone, ParentNsRecord
  RootHostedZoneBinding:
    IncludeMasterAccount: true

Conditions:
    HasNot: !Equals [ 'true', 'false' ]

Resources:

  #=========================================#
  # Zone
  #=========================================#

  HostedZone:
    Type: AWS::Route53::HostedZone
    OrganizationBinding: !Ref HostedZoneBinding
    Properties:
      HostedZoneConfig:
        Comment: Domain Hosted Zone
      Name: !Sub '${AWSAccount.Tags.subdomain}.${rootHostedZoneName}.'

  HostedZoneIdParam:
    Type: AWS::SSM::Parameter
    OrganizationBinding: !Ref HostedZoneBinding
    Properties:
      Name: !Sub '${resourcePrefix}-domains-hosted-zone-id'
      Type: String
      Value: !GetAtt AWSAccount.Resources.HostedZone

  HostedZoneNameParam:
    Type: AWS::SSM::Parameter
    OrganizationBinding: !Ref HostedZoneBinding
    Properties:
      Name: !Sub '${resourcePrefix}-domains-hosted-zone-name'
      Type: String
      Value: !Sub '${AWSAccount.Tags.subdomain}.${rootHostedZoneName}.'

  #=========================================#
  # Parent Record
  #=========================================#

# dummy (null) resource, never created
  NullResource:
    Type: 'Custom::NullResource'
    Condition: HasNot
    OrganizationBinding:
      IncludeMasterAccount: true

  # RootHostedZone:
  #   Type: AWS::Route53::HostedZone
  #   OrganizationBinding: !Ref RootHostedZoneBinding
  #   Properties:
  #     HostedZoneConfig:
  #       Comment: Root domain
  #     Name: !Ref rootHostedZoneName

  # be aware that changing the logicalName for a AWS::Route53::RecordSet resource
  # might result in an error. workaround is to remove the resource and then add it.
  ParentNsRecord:
    # DependsOn: RootHostedZone
    Type: AWS::Route53::RecordSet
    OrganizationBinding: !Ref RootHostedZoneBinding
    ForeachAccount: !Ref HostedZoneBinding
    Properties:
      Type: NS
      HostedZoneName: !Sub '${rootHostedZoneName}.'
      Name: !Sub '${CurrentAccount.Tags.subdomain}.${rootHostedZoneName}.'
      TTL: 86400 # 24h
      ResourceRecords: !GetAtt CurrentAccount.Resources.HostedZone.NameServers


CatenaryCloudHQ avatar Apr 25 '22 01:04 CatenaryCloudHQ