How can I get an existing ApplicationLoadBalancer?...
# general
m
How can I get an existing ApplicationLoadBalancer?
Copy code
// has missing properties error when I try to use it
const alb = pulumi.output(<http://aws.lb|aws.lb>.getLoadBalancer({
  // @ts-ignore
  arn: stackSandbox.getOutput("albArn")
}));

// declares a new ALB
const alb = new <http://awsx.lb|awsx.lb>.ApplicationLoadBalancer("test-default-lb", {
  // @ts-ignore
  arn: stackSandbox.getOutput("albArn"),
  subnets: stackSandbox.getOutput("publicSubnetIds").apply(v => v),
  vpc
});
a
<http://awsx.lb|awsx.lb>.ApplicationLoadBalancer.get()
You'll need a name parameter and an id parameter if the AWS sdk is the same as the Azure sdk
m
Copy code
TS2339: Property 'get' does not exist on type 'typeof ApplicationLoadBalancer'.
a
Copy code
// Get reference to pre-existing Azure ResourceGroup
// get the Azure Resource Group
var resouceGroupId:pulumi.Output<string> = pulumi.interpolate `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}`;
const resourceGroup = azure.core.ResourceGroup.get(resourceGroupName, resouceGroupId);
This is my code for getting an existing Resource Group in Azure
b
@millions-furniture-75402 you could also try the import https://www.pulumi.com/docs/guides/adopting/import/
m
Thank you both, I will explore these options and get back to you
I assume I’ll be in a similar situation for the Listener I created in another stack as well
Would this be the correct syntax?
Copy code
const alb = new <http://awsx.lb|awsx.lb>.ApplicationLoadBalancer("test-default-lb", {
  // @ts-ignore
  arn: stackSandbox.getOutput("albArn"),
  subnets: stackSandbox.getOutput("publicSubnetIds").apply(v => v),
  vpc
}, { import: stackSandbox.getOutput("albArn") });
seems odd that I have to redeclare the vpc and subnets if I’m specifying the arn
a
That looks like the right syntax. You may be able to leave the
options
object null or
{}
👍 1
b
your options have to match the current resource, or the import will fail
👍 1
m
Is there a clever way to keep this DRYer? I’m guessing defining custom ComponentResources that hide this dirty work?
a
I'm not sure importing a resource into a second stack is the right approach.
b
what exactly are you working on right now?
a
If the resource is defined/created in the first stack, you should just
.get()
it in the second stack. the
import
directive will bring that resource into the second stack and start to manage it.
My resourceGroup example, that resource group is not managed by a Pulumi stack at all.
m
I have a shared-infra stack that creates and ALB with default http and https listeners. Then I have an application stack where I want to create an application TargetGroup and attach it to the ALB, and add a ListenerRule to handle host-based routing.
The only thing I’m not declaring in the shared-infra stack is the VPC which is pre-existing.
a
Your application stack shouldn't use the import directive imho
m
@ancient-megabyte-79588 I’m not sure what to do if there is no .get() on the ApplicationLoadBalancer, other than redeclare it all without Crosswalk, which seems like a pain.
a
@billowy-army-68599 should have some guidance! 😄
👍 1
I don't know why there would be no
.get()
method on the AWS SDK. 😞
b
yes, @ancient-megabyte-79588 is correct, you probably don't want to use import in this case. Our usual recommendation in this scenarios is to output the IDs/properties of the resources you declare in the shared infra stacks and use them as inputs in your dependent stacks, a bit like this https://github.com/pulumi/examples/tree/master/aws-stackreference-architecture
m
yeah, that’s what I’m doing, but I need the ALB instance object to pass to my TargetGroup creation, for example.
Copy code
const appTargetGroup = new <http://awsx.lb|awsx.lb>.ApplicationTargetGroup(`${appName}-tg`, {
  loadBalancer: alb,
  ...
Similarly, I’ll have to use the instance of the https listener to add a rule
Copy code
const appListenerRule = new <http://awsx.lb|awsx.lb>.ListenerRule(`${appName}-lr`, httpsListener, {
  actions: [{
    targetGroupArn: appTargetGroup.targetGroup.arn,
    type: "forward",
  }],
 conditions: [{
    hostHeader: {
      values: [`${appName}.*`],
    },
  }],
  priority: 1,
});
Though against best practices, I tried the suggestion of using import, and pulumi is still trying to recreate the ALB:
Copy code
const lbSecurityGroup = new awsx.ec2.SecurityGroup(`${appName}-default-http-and-https`, {
  vpc
}, {
  // @ts-ignore
  import: stackSandbox.getOutput("lbSecurityGroupArn")
});

const alb = new <http://awsx.lb|awsx.lb>.ApplicationLoadBalancer("test-default-lb", {
  external: true,
  securityGroups: [lbSecurityGroup],
  // @ts-ignore
  subnets: stackSandbox.getOutput("publicSubnetIds").apply(v => v),
  vpc,
}, {
  // @ts-ignore
  import: stackSandbox.getOutput("albArn").apply(v => v)
});
I guess that’s because ApplicationLoadBalancer is an abstraction of many resources, and doesn’t have it’s own ID… so it has the resource IDs… but then I’m back to almost redefining the entire ApplicationLoadBalancer.
I guess for now, I’ll just have to spin up multiple load balancers as awsx does not seem to consider the use case for sharing an ALB with many applications.
a
Why don't you spin up the ALB in the application since it is directly tied to the application more so than the infrastructure?
No point in having an ALB with nothing to run it against. 😄
m
Was hoping to use 1 ALB for many application stacks that don’t see a lot of traffic
👍 1
f
I'd like to do this too. I want to send traffic to one of two application servers based on path. I'm new to Pulumi, so maybe I'm missing something obvious. But based on this thread it doesn't seem possible, so I filed a feature request https://github.com/pulumi/pulumi/issues/5024
👍 1
m
Last I checked, this slack community will cull message to 10,000, so just be aware this conversation could disappear.
f
Thanks for the heads up. I sent I PR for this: https://github.com/pulumi/pulumi-awsx/pull/548. Now just need to wait for a review...
👍 1