diff --git a/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/__tests__/staticweb.ts b/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/__tests__/staticweb.ts index e884d95..882593a 100644 --- a/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/__tests__/staticweb.ts +++ b/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/__tests__/staticweb.ts @@ -112,7 +112,7 @@ describe("Minimal configuration", function () { }; expect(throwError).toThrow( - /It's\snot\spossible\sto\sconfig\sthe\sdomain\.*/ + /It's\snot\spossible\sto\sautomatically\sconfigure\sthe\sdomain\.*/ ); }); }); diff --git a/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/staticweb.ts b/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/staticweb.ts index fdda7e5..c6787a1 100644 --- a/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/staticweb.ts +++ b/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/staticweb.ts @@ -1,31 +1,41 @@ import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; import defaultsDeep from "lodash.defaultsdeep"; -import { StaticWebArgs, DNSRecordsArgs, defaultArgs } from "./staticwebArgs"; +import { + StaticWebArgs, + DNSRecordsArgs, + DomainPartsArgs, + defaultArgs, +} from "./staticwebArgs"; import { Bucket, BucketArgs } from "../storage"; export { StaticWebArgs, DNSRecordsArgs }; export const TYPENAME_STATICWEB = "cloud-toolkit-aws:serverless:StaticWeb"; -function getDomainAndSubdomain(domain: string): { - subdomain: string; - parentDomain: string; -} { - const parts = domain.split("."); - if (parts.length < 2) { - throw new Error(`No TLD found on ${domain}`); - } - if (parts.length === 2) { - return { subdomain: "", parentDomain: domain }; - } +function getDomainAndSubdomain( + domain: string, + domainParts: DomainPartsArgs | undefined +): DomainPartsArgs { + + if (domainParts === undefined) { + const parts = domain.split("."); + if (parts.length < 2) { + throw new Error(`No TLD found on ${domain}`); + } + if (parts.length === 2) { + return { subdomain: "", parentDomain: domain }; + } - const subdomain = parts[0]; - parts.shift(); - return { - subdomain, - parentDomain: parts.join(".") + ".", - }; + const subdomain = parts[0]; + parts.shift(); + return { + subdomain, + parentDomain: parts.join(".") + ".", + }; + } else { + return domainParts; + } } export class StaticWeb extends pulumi.ComponentResource { @@ -163,7 +173,13 @@ export class StaticWeb extends pulumi.ComponentResource { if (config.domain != null && !config.configureDNS) { throw new Error( - `It's not possible to config the domain ${args.domain} without configuring a DNS` + `It's not possible to automatically configure the domain ${config.domain} without configuring the DNS` + ); + } + + if (config.domainParts != null && !config.domain) { + throw new Error( + `The domain is required to configure the needed certificates. domainParts is used to manually configure the hosted zone and the DNS Records. Using domainParts requires setting domain as well` ); } @@ -279,9 +295,9 @@ export class StaticWeb extends pulumi.ComponentResource { throw new Error("Domain validation options must be defined"); } - const domainParts = getDomainAndSubdomain(domain); + const domainParts = getDomainAndSubdomain(domain, args.domainParts); - var hostedZoneId: pulumi.Input = ""; + let hostedZoneId: pulumi.Input = ""; if (args.dns === undefined || args.dns.hostedZoneId === undefined) { hostedZoneId = aws.route53 @@ -363,9 +379,9 @@ export class StaticWeb extends pulumi.ComponentResource { throw new Error("Domain field must be defined"); } - const domainParts = getDomainAndSubdomain(domain); + const domainParts = getDomainAndSubdomain(domain, args.domainParts); - var hostedZoneId: pulumi.Input = ""; + let hostedZoneId: pulumi.Input = ""; if (args.dns === undefined || args.dns.hostedZoneId === undefined) { hostedZoneId = aws.route53 diff --git a/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/staticwebArgs.ts b/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/staticwebArgs.ts index ad28f7d..d5a1517 100644 --- a/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/staticwebArgs.ts +++ b/provider/cmd/pulumi-resource-cloud-toolkit-aws/serverless/staticwebArgs.ts @@ -5,9 +5,18 @@ import * as aws from "@pulumi/aws"; */ export interface StaticWebArgs { /** - * Set to true to add an alias to wwww. + * Domain that will point to the Cloud Front distribution. The hosted zone is automatically extracted by removing the first subdomain. + * e.g. my.nice.website.com -> my - subdomain | nice.website.com - hosted zone. + * The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + * configureDNS should be set to true. */ domain?: string; + /** + * Subdomain and parent domain of the DNS Record. The parent domain is used to determine the hosted zone that will hold the DNS Record. + * The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + * Used alongside domain. configureDNS should be set to true. + */ + domainParts?: DomainPartsArgs /** * Set to true to add an alias to wwww. */ @@ -40,6 +49,20 @@ export interface CdnCacheArgs { ttl: number; } +/** + * Arguments to manually configure the domain of the DNS Record that points to the CloudFront distribution + */ +export interface DomainPartsArgs { + /** + * Subdomain part that will be the name of the DNS Record + */ + subdomain: string; + /** + * Domain used to extract the hosted zone id for the DNS Record + */ + parentDomain: string; +} + /** * Arguments to configure the DNS */ diff --git a/schema.yaml b/schema.yaml index 1ed08d5..aca3207 100644 --- a/schema.yaml +++ b/schema.yaml @@ -1510,6 +1510,15 @@ types: domain: description: Set to true to add an alias to wwww. type: string + domainParts: + description: >- + Subdomain and parent domain of the DNS Record. The parent domain is + used to determine the hosted zone that will hold the DNS Record. + + The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + + Used alongside domain. configureDNS should be set to true. + $ref: "#/types/cloud-toolkit-aws:serverless:DomainParts" includeWWW: description: Set to true to add an alias to wwww. type: boolean @@ -1535,6 +1544,15 @@ types: type: object required: - ttl + cloud-toolkit-aws:serverless:DomainParts: + properties: + subdomain: + description: Subdomain part that will be the name of the DNS Record + type: string + parentDomain: + description: Domain used to extract the hosted zone id for the DNS Record + type: string + type: object cloud-toolkit-aws:serverless:CdnDns: properties: ttl: @@ -3343,8 +3361,25 @@ resources: - distribution inputProperties: domain: - description: Set to true to add an alias to wwww. + description: >- + Domain that will point to the Cloud Front distribution. The hosted + zone is automatically extracted by removing the first subdomain. + + e.g. my.nice.website.com -> my - subdomain | nice.website.com - hosted zone. + + The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + + configureDNS should be set to true. type: string + domainParts: + description: >- + Subdomain and parent domain of the DNS Record. The parent domain is + used to determine the hosted zone that will hold the DNS Record. + + The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + + Used alongside domain. configureDNS should be set to true. + $ref: "#/types/cloud-toolkit-aws:serverless:DomainParts" includeWWW: description: Set to true to add an alias to wwww. type: boolean diff --git a/sdk/nodejs/serverless/staticWeb.ts b/sdk/nodejs/serverless/staticWeb.ts index 00a04dd..5bcb135 100644 --- a/sdk/nodejs/serverless/staticWeb.ts +++ b/sdk/nodejs/serverless/staticWeb.ts @@ -90,6 +90,7 @@ export class StaticWeb extends pulumi.ComponentResource { resourceInputs["configureDNS"] = args ? args.configureDNS : undefined; resourceInputs["dns"] = args ? args.dns : undefined; resourceInputs["domain"] = args ? args.domain : undefined; + resourceInputs["domainParts"] = args ? args.domainParts : undefined; resourceInputs["includeWWW"] = args ? args.includeWWW : undefined; resourceInputs["priceClass"] = args ? args.priceClass : undefined; resourceInputs["DNSRecords"] = undefined /*out*/; @@ -140,9 +141,18 @@ export interface StaticWebArgs { */ dns?: pulumi.Input; /** - * Set to true to add an alias to wwww. + * Domain that will point to the Cloud Front distribution. The hosted zone is automatically extracted by removing the first subdomain. + * e.g. my.nice.website.com -> my - subdomain | nice.website.com - hosted zone. + * The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + * configureDNS should be set to true. */ domain?: pulumi.Input; + /** + * Subdomain and parent domain of the DNS Record. The parent domain is used to determine the hosted zone that will hold the DNS Record. + * The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + * Used alongside domain. configureDNS should be set to true. + */ + domainParts?: pulumi.Input; /** * Set to true to add an alias to wwww. */ diff --git a/sdk/nodejs/types/serverless/input.ts b/sdk/nodejs/types/serverless/input.ts index a0c55fa..3e4934a 100644 --- a/sdk/nodejs/types/serverless/input.ts +++ b/sdk/nodejs/types/serverless/input.ts @@ -47,6 +47,17 @@ export interface DeadLetterQueueTypeArgs { type: pulumi.Input; } +export interface DomainPartsArgs { + /** + * Domain used to extract the hosted zone id for the DNS Record + */ + parentDomain?: pulumi.Input; + /** + * Subdomain part that will be the name of the DNS Record + */ + subdomain?: pulumi.Input; +} + export interface QueueArgs { /** * Dead Letter Queue attached to the component to create. diff --git a/sdk/python/cloud_toolkit_aws/serverless/_inputs.py b/sdk/python/cloud_toolkit_aws/serverless/_inputs.py index 45cb104..1bf5502 100644 --- a/sdk/python/cloud_toolkit_aws/serverless/_inputs.py +++ b/sdk/python/cloud_toolkit_aws/serverless/_inputs.py @@ -14,6 +14,7 @@ 'CdnCacheArgs', 'CdnDnsArgs', 'DeadLetterQueueTypeArgs', + 'DomainPartsArgs', 'QueueArgs', ] @@ -145,6 +146,45 @@ def message_retention_seconds(self, value: Optional[pulumi.Input[float]]): pulumi.set(self, "message_retention_seconds", value) +@pulumi.input_type +class DomainPartsArgs: + def __init__(__self__, *, + parent_domain: Optional[pulumi.Input[str]] = None, + subdomain: Optional[pulumi.Input[str]] = None): + """ + :param pulumi.Input[str] parent_domain: Domain used to extract the hosted zone id for the DNS Record + :param pulumi.Input[str] subdomain: Subdomain part that will be the name of the DNS Record + """ + if parent_domain is not None: + pulumi.set(__self__, "parent_domain", parent_domain) + if subdomain is not None: + pulumi.set(__self__, "subdomain", subdomain) + + @property + @pulumi.getter(name="parentDomain") + def parent_domain(self) -> Optional[pulumi.Input[str]]: + """ + Domain used to extract the hosted zone id for the DNS Record + """ + return pulumi.get(self, "parent_domain") + + @parent_domain.setter + def parent_domain(self, value: Optional[pulumi.Input[str]]): + pulumi.set(self, "parent_domain", value) + + @property + @pulumi.getter + def subdomain(self) -> Optional[pulumi.Input[str]]: + """ + Subdomain part that will be the name of the DNS Record + """ + return pulumi.get(self, "subdomain") + + @subdomain.setter + def subdomain(self, value: Optional[pulumi.Input[str]]): + pulumi.set(self, "subdomain", value) + + @pulumi.input_type class QueueArgs: def __init__(__self__, *, diff --git a/sdk/python/cloud_toolkit_aws/serverless/static_web.py b/sdk/python/cloud_toolkit_aws/serverless/static_web.py index 8f1840b..40b4522 100644 --- a/sdk/python/cloud_toolkit_aws/serverless/static_web.py +++ b/sdk/python/cloud_toolkit_aws/serverless/static_web.py @@ -22,6 +22,7 @@ def __init__(__self__, *, configure_dns: Optional[pulumi.Input[bool]] = None, dns: Optional[pulumi.Input['CdnDnsArgs']] = None, domain: Optional[pulumi.Input[str]] = None, + domain_parts: Optional[pulumi.Input['DomainPartsArgs']] = None, include_www: Optional[pulumi.Input[bool]] = None, price_class: Optional[pulumi.Input[str]] = None): """ @@ -29,7 +30,13 @@ def __init__(__self__, *, :param pulumi.Input['CdnCacheArgs'] cache: Cloud Front distribution cache :param pulumi.Input[bool] configure_dns: Set to true to configure DNS :param pulumi.Input['CdnDnsArgs'] dns: DNS configuration - :param pulumi.Input[str] domain: Set to true to add an alias to wwww. + :param pulumi.Input[str] domain: Domain that will point to the Cloud Front distribution. The hosted zone is automatically extracted by removing the first subdomain. + e.g. my.nice.website.com -> my - subdomain | nice.website.com - hosted zone. + The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + configureDNS should be set to true. + :param pulumi.Input['DomainPartsArgs'] domain_parts: Subdomain and parent domain of the DNS Record. The parent domain is used to determine the hosted zone that will hold the DNS Record. + The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + Used alongside domain. configureDNS should be set to true. :param pulumi.Input[bool] include_www: Set to true to add an alias to wwww. :param pulumi.Input[str] price_class: Cloud Front distribution priceClass """ @@ -41,6 +48,8 @@ def __init__(__self__, *, pulumi.set(__self__, "dns", dns) if domain is not None: pulumi.set(__self__, "domain", domain) + if domain_parts is not None: + pulumi.set(__self__, "domain_parts", domain_parts) if include_www is not None: pulumi.set(__self__, "include_www", include_www) if price_class is not None: @@ -86,7 +95,10 @@ def dns(self, value: Optional[pulumi.Input['CdnDnsArgs']]): @pulumi.getter def domain(self) -> Optional[pulumi.Input[str]]: """ - Set to true to add an alias to wwww. + Domain that will point to the Cloud Front distribution. The hosted zone is automatically extracted by removing the first subdomain. + e.g. my.nice.website.com -> my - subdomain | nice.website.com - hosted zone. + The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + configureDNS should be set to true. """ return pulumi.get(self, "domain") @@ -94,6 +106,20 @@ def domain(self) -> Optional[pulumi.Input[str]]: def domain(self, value: Optional[pulumi.Input[str]]): pulumi.set(self, "domain", value) + @property + @pulumi.getter(name="domainParts") + def domain_parts(self) -> Optional[pulumi.Input['DomainPartsArgs']]: + """ + Subdomain and parent domain of the DNS Record. The parent domain is used to determine the hosted zone that will hold the DNS Record. + The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + Used alongside domain. configureDNS should be set to true. + """ + return pulumi.get(self, "domain_parts") + + @domain_parts.setter + def domain_parts(self, value: Optional[pulumi.Input['DomainPartsArgs']]): + pulumi.set(self, "domain_parts", value) + @property @pulumi.getter(name="includeWWW") def include_www(self) -> Optional[pulumi.Input[bool]]: @@ -128,6 +154,7 @@ def __init__(__self__, configure_dns: Optional[pulumi.Input[bool]] = None, dns: Optional[pulumi.Input[pulumi.InputType['CdnDnsArgs']]] = None, domain: Optional[pulumi.Input[str]] = None, + domain_parts: Optional[pulumi.Input[pulumi.InputType['DomainPartsArgs']]] = None, include_www: Optional[pulumi.Input[bool]] = None, price_class: Optional[pulumi.Input[str]] = None, __props__=None): @@ -138,7 +165,13 @@ def __init__(__self__, :param pulumi.Input[pulumi.InputType['CdnCacheArgs']] cache: Cloud Front distribution cache :param pulumi.Input[bool] configure_dns: Set to true to configure DNS :param pulumi.Input[pulumi.InputType['CdnDnsArgs']] dns: DNS configuration - :param pulumi.Input[str] domain: Set to true to add an alias to wwww. + :param pulumi.Input[str] domain: Domain that will point to the Cloud Front distribution. The hosted zone is automatically extracted by removing the first subdomain. + e.g. my.nice.website.com -> my - subdomain | nice.website.com - hosted zone. + The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + configureDNS should be set to true. + :param pulumi.Input[pulumi.InputType['DomainPartsArgs']] domain_parts: Subdomain and parent domain of the DNS Record. The parent domain is used to determine the hosted zone that will hold the DNS Record. + The subdomain is used as the name of the DNS Record that points to the Cloud Front distribution. + Used alongside domain. configureDNS should be set to true. :param pulumi.Input[bool] include_www: Set to true to add an alias to wwww. :param pulumi.Input[str] price_class: Cloud Front distribution priceClass """ @@ -169,6 +202,7 @@ def _internal_init(__self__, configure_dns: Optional[pulumi.Input[bool]] = None, dns: Optional[pulumi.Input[pulumi.InputType['CdnDnsArgs']]] = None, domain: Optional[pulumi.Input[str]] = None, + domain_parts: Optional[pulumi.Input[pulumi.InputType['DomainPartsArgs']]] = None, include_www: Optional[pulumi.Input[bool]] = None, price_class: Optional[pulumi.Input[str]] = None, __props__=None): @@ -186,6 +220,7 @@ def _internal_init(__self__, __props__.__dict__["configure_dns"] = configure_dns __props__.__dict__["dns"] = dns __props__.__dict__["domain"] = domain + __props__.__dict__["domain_parts"] = domain_parts __props__.__dict__["include_www"] = include_www __props__.__dict__["price_class"] = price_class __props__.__dict__["dns_records"] = None