Hi everyone, I'm running into issues with Pulumi, ...
# typescript
g
Hi everyone, I'm running into issues with Pulumi, AWS and Typescript. For some reason typescript thinks some resources are undefined and fails when I do a
pulumi up --diff
. Code:
Copy code
export const hostedZoneAppARecord = new aws.route53.Record(
    'hostedZoneAppARecord',
    {
        name: `app.${config.require('hosted_zone_domain')}`,
        type: aws.route53.RecordType.A,
        zoneId: hostedZone.zoneId,
        aliases: [
            {
                name: distribution.domainName.apply((domainName) => domainName),
                evaluateTargetHealth: false,
                zoneId: distribution.hostedZoneId.apply(
                    (hostedZoneId) => hostedZoneId
                )
            }
        ]
    },
    { dependsOn: [distribution] }
);
Error:
Copy code
[urn=urn:pulumi:dev::redacted::pulumi:pulumi:Stack::redacted]                                                                                                                                                       error: Running program 'redacted/index.ts' failed with an unhandled exception:
TypeError: Cannot read properties of undefined (reading 'domainName')
The undefined thing it complains about is
distribution
. I'm loading everything via barrel files. (export * from './file'). Distribution is loaded before the DNS record in the index. Does anyone have any ideas?
l
You'll have to show us how you create and load that missing variable. The code here misses the but that needs to be fixed.
g
so I have a distribution.ts file with the following:
Copy code
export const distribution = new cloudfront.Distribution(
    'Distribution',
    {
        aliases: [domain, `app.${domain}`],
        defaultCacheBehavior: {
            allowedMethods: ['GET', 'HEAD'],
            cachePolicyId: '658327ea-f89d-4fab-a63d-7e88639e58f6',
            cachedMethods: ['GET', 'HEAD'],
            compress: true,
            targetOriginId: 'bucket',
            viewerProtocolPolicy: 'redirect-to-https',
            functionAssociations: [
                {
                    eventType: 'viewer-request',
                    functionArn: redirectFunction.arn
                }
            ]
        },
        defaultRootObject: 'index.html',
        enabled: true,
        isIpv6Enabled: false,
        orderedCacheBehaviors: [
            {
                allowedMethods: ['POST', 'GET', 'HEAD', 'PATCH', 'DELETE', 'OPTIONS', 'PUT'],
                cachePolicyId: '4135ea2d-6df8-44a3-9df3-4b5a84be39ad',
                cachedMethods: ['GET', 'HEAD'],
                compress: true,
                originRequestPolicyId: '216adef6-5c7f-47e4-b989-5492eafa07d3',
                pathPattern: '/api/*',
                targetOriginId: 'load-balancer',
                viewerProtocolPolicy: 'redirect-to-https'
            },
            {
                cachePolicyId: '658327ea-f89d-4fab-a63d-7e88639e58f6',
                pathPattern: '/files/*',
                allowedMethods: ['GET', 'HEAD'],
                targetOriginId: fileBucket.bucketDomainName,
                cachedMethods: ['GET', 'HEAD'],
                viewerProtocolPolicy: 'redirect-to-https',
                compress: true,
                trustedKeyGroups: [fileBucketKeyGroup.id]
            }
        ],
        origins: [
            {
                domainName: frontendBucket.bucketDomainName,
                originId: 'origin-id',
                s3OriginConfig: {
                    originAccessIdentity: originAccessIdentity.cloudfrontAccessIdentityPath
                }
            },
            {
                domainName: fileBucket.bucketDomainName,
                originId: fileBucket.bucketDomainName,
                originAccessControlId: originAccessControl.id
            },
            {
                customOriginConfig: {
                    httpPort: 80,
                    httpsPort: 443,
                    originProtocolPolicy: 'match-viewer',
                    originSslProtocols: ['TLSv1.2']
                },
                domainName: ingressALB.status.loadBalancer.ingress.apply(([x]) => x.hostname),
                originId: 'load-balancer',
                customHeaders: [
                    {
                        name: 'X-Custom-Header',
                        value: 'redacted'
                    }
                ]
            }
        ],
        restrictions: {
            geoRestriction: {
                restrictionType: 'none'
            }
        },
        viewerCertificate: {
            acmCertificateArn: certificateArn,
            minimumProtocolVersion: 'TLSv1.2_2021',
            sslSupportMethod: 'sni-only'
        }
    },
    {
        protect: true
    }
);
I then have several index files. which look like this: distribution/index.ts:
export * from './distribution'
route53/index.ts:
export * from './domain'
Then in my main index:
export * from './distribution'
export * from './route53'
It can deploy and work fine, so long as I don't try to reference it with the route 53 code. At the moment the distribution is deployed as it had a lot of manual assistance with creating the domains initially. I'm trying to make things more maintainable by moving the route 53 things into pulumi given that we are changing domains now.
l
Are you importing it anywhere?
How are you getting at that
distribution
value?
g
Yeah, so in that file with the hostedZoneAppARecord, I have this at the top:
Copy code
import { distribution } from '../cloudfront';
l
Ah. So you're exporting
distribution
from distribution.ts and then importing it from cloudfront.ts? That might be the problem. I would certainly be investigating that value of
distribution
at various points. Given the code you've posted, there's no problem with the Pulumi parts. The only problem is that
distribution
is null when you're trying to dereference it.
g
That might be the problem
Turns out it was the problem. I removed the index files and directly imported the things as needed and it worked. Thank you for your help 🙂
l
Index files do work fine, but the right syntax isn't always obvious. Once you've got the Pulumi parts working you can refactor for tidiness 🙂