Skip to content

Commit

Permalink
Merge pull request #121 from lbrlabs/routes
Browse files Browse the repository at this point in the history
feat(AWS/Azure): support for multiple routes
  • Loading branch information
jaxxstorm committed Mar 19, 2024
2 parents 6922891 + 2a92a78 commit 8db73c3
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 75 deletions.
25 changes: 16 additions & 9 deletions provider/pkg/provider/aws/bastion.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"strings"
"text/template"

"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/autoscaling"
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ec2"
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam"
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ssm"
"github.com/pulumi/pulumi-tailscale/sdk/go/tailscale"
tls "github.com/pulumi/pulumi-tls/sdk/v4/go/tls"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"strings"
"text/template"
)

var (
Expand All @@ -28,7 +27,7 @@ type BastionArgs struct {
VpcID pulumi.StringInput `pulumi:"vpcId"`
SubnetIds pulumi.StringArrayInput `pulumi:"subnetIds"`
TailscaleTags pulumi.StringArrayInput `pulumi:"tailscaleTags"`
Route pulumi.StringInput `pulumi:"route"`
Routes pulumi.StringArrayInput `pulumi:"routes"`
Region pulumi.StringInput `pulumi:"region"`
InstanceType pulumi.StringInput `pulumi:"instanceType"`
Hostname pulumi.StringInput `pulumi:"hostname"`
Expand All @@ -41,7 +40,7 @@ type BastionArgs struct {

type UserDataArgs struct {
ParameterName string
Route string
Routes string
Region string
TailscaleTags string
EnableSSH bool
Expand All @@ -50,7 +49,6 @@ type UserDataArgs struct {
Hostname string
}


// The Bastion component resource.
type Bastion struct {
pulumi.ResourceState
Expand Down Expand Up @@ -275,14 +273,23 @@ func NewBastion(ctx *pulumi.Context,
MostRecent: pulumi.BoolPtr(true),
}, pulumi.Parent(component))

data := pulumi.All(tailnetKeySsmParameter.Name, args.Route, args.Region, args.TailscaleTags, args.EnableSSH, hostname, args.EnableExitNode, args.EnableAppConnector).ApplyT(
data := pulumi.All(tailnetKeySsmParameter.Name, args.Routes, args.Region, args.TailscaleTags, args.EnableSSH, hostname, args.EnableExitNode, args.EnableAppConnector).ApplyT(
func(args []interface{}) (string, error) {

tagCSV := strings.Join(args[3].([]string), ",")
tagCSV := strings.Join(args[3].([]string), ",")

var routesCsv string

if args[1] != nil {
routes := args[1].([]string)
routesCsv = strings.Join(routes, ",")
} else {
routesCsv = ""
}

d := UserDataArgs{
ParameterName: args[0].(string),
Route: args[1].(string),
Routes: routesCsv,
Region: args[2].(string),
TailscaleTags: tagCSV,
EnableSSH: args[4].(bool),
Expand Down
2 changes: 1 addition & 1 deletion provider/pkg/provider/aws/userdata.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ sudo yum-config-manager --add-repo https://pkgs.tailscale.com/stable/amazon-linu
sudo yum install tailscale -y
sudo systemctl enable --now tailscaled
sleep 10
sudo tailscale up --advertise-connector="{{ .EnableAppConnector }}" --advertise-exit-node="{{ .EnableExitNode }}" --hostname="{{ .Hostname}}" --ssh="{{ .EnableSSH }}" --advertise-tags="{{ .TailscaleTags}}" --advertise-routes="{{ .Route }}" --authkey=$(aws ssm get-parameter --name {{.ParameterName}} --region {{.Region}} --with-decryption | jq .Parameter.Value -r) --host-routes
sudo tailscale up --advertise-connector="{{ .EnableAppConnector }}" --advertise-exit-node="{{ .EnableExitNode }}" --hostname="{{ .Hostname}}" --ssh="{{ .EnableSSH }}" --advertise-tags="{{ .TailscaleTags}}" {{if .Routes}}--advertise-routes="{{ .Routes }}"{{end}} --authkey=$(aws ssm get-parameter --name {{.ParameterName}} --region {{.Region}} --with-decryption | jq .Parameter.Value -r) --host-routes
68 changes: 46 additions & 22 deletions provider/pkg/provider/azure/bastion.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,27 @@ var (

// The set of arguments for creating a Bastion component resource.
type BastionArgs struct {
ResourceGroupName pulumi.StringInput `pulumi:"resourceGroupName"`
SubnetID pulumi.StringInput `pulumi:"subnetId"`
Location pulumi.StringInput `pulumi:"location"`
Route pulumi.StringInput `pulumi:"route"`
InstanceSku pulumi.StringInput `pulumi:"instanceSku"`
TailscaleTags pulumi.StringArrayInput `pulumi:"tailscaleTags"`
HighAvailability bool `pulumi:"highAvailability"`
EnableSSH bool `pulumi:"enableSSH"`
ResourceGroupName pulumi.StringInput `pulumi:"resourceGroupName"`
SubnetID pulumi.StringInput `pulumi:"subnetId"`
Location pulumi.StringInput `pulumi:"location"`
Routes pulumi.StringArrayInput `pulumi:"routes"`
InstanceSku pulumi.StringInput `pulumi:"instanceSku"`
TailscaleTags pulumi.StringArrayInput `pulumi:"tailscaleTags"`
Hostname pulumi.StringInput `pulumi:"hostname"`
HighAvailability bool `pulumi:"highAvailability"`
EnableSSH bool `pulumi:"enableSSH"`
EnableExitNode bool `pulumi:"enableExitNode"`
EnableAppConnector bool `pulumi:"enableAppConnector"`
}

type UserDataArgs struct {
AuthKey string
Route string
TailscaleTags []string
EnableSSH bool
}

// Join the tags into a CSV
func (uda *UserDataArgs) JoinedTags() string {
return strings.Join(uda.TailscaleTags, ",")
AuthKey string
Routes string
TailscaleTags string
EnableSSH bool
EnableExitNode bool
EnableAppConnector bool
Hostname string
}

// The Bastion component resource.
Expand All @@ -65,6 +66,14 @@ func NewBastion(ctx *pulumi.Context,
return nil, err
}

var hostname pulumi.StringInput

if args.Hostname == nil {
hostname = pulumi.String(name)
} else {
hostname = args.Hostname
}

// create a tailnet key to auth devices
tailnetKey, err := tailscale.NewTailnetKey(ctx, name, &tailscale.TailnetKeyArgs{
Ephemeral: pulumi.Bool(true),
Expand All @@ -76,13 +85,28 @@ func NewBastion(ctx *pulumi.Context,
return nil, fmt.Errorf("error creating tailnet key: %v", err)
}

data := pulumi.All(tailnetKey.Key, args.Route, args.TailscaleTags, args.EnableSSH).ApplyT(
data := pulumi.All(tailnetKey.Key, args.Routes, args.TailscaleTags, args.EnableSSH, hostname, args.EnableExitNode, args.EnableAppConnector).ApplyT(
func(args []interface{}) (string, error) {

tagCSV := strings.Join(args[3].([]string), ",")

var routesCsv string

if args[1] != nil {
routes := args[1].([]string)
routesCsv = strings.Join(routes, ",")
} else {
routesCsv = ""
}

d := UserDataArgs{
AuthKey: args[0].(string),
Route: args[1].(string),
TailscaleTags: args[2].([]string),
EnableSSH: args[3].(bool),
AuthKey: args[0].(string),
Routes: routesCsv,
TailscaleTags: tagCSV,
EnableSSH: args[3].(bool),
Hostname: args[4].(string),
EnableExitNode: args[5].(bool),
EnableAppConnector: args[6].(bool),
}

var userDataBytes bytes.Buffer
Expand Down
2 changes: 1 addition & 1 deletion provider/pkg/provider/azure/userdata.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO
sudo apt-get update
sudo apt-get install azure-cli tailscale

sudo tailscale up --ssh="{{ .EnableSSH }}" --advertise-tags="{{ .JoinedTags }}" --advertise-routes="{{ .Route }}" --authkey="{{ .AuthKey }}" --host-routes --accept-dns=false
sudo tailscale up --advertise-connector="{{ .EnableAppConnector }}" --advertise-exit-node="{{ .EnableExitNode }}" --hostname="{{ .Hostname}}" --ssh="{{ .EnableSSH }}" --advertise-tags="{{ .TailscaleTags}}" {{if .Routes}}--advertise-routes="{{ .Routes }}"{{end}} --authkey=$(aws ssm get-parameter --name {{.ParameterName}} --region {{.Region}} --with-decryption | jq .Parameter.Value -r) --host-routes
9 changes: 5 additions & 4 deletions schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ resources:
items:
type: string
description: "The subnet Ids to launch instances in."
route:
type: string
description: "The route you'd like to advertise via tailscale."
routes:
type: array
items:
type: string
description: "The routes you'd like to advertise via tailscale."
region:
type: string
description: "The AWS region you're using."
Expand All @@ -113,7 +115,6 @@ resources:
- highAvailability
- vpcId
- subnetIds
- route
- region
- tailscaleTags
properties:
Expand Down
12 changes: 9 additions & 3 deletions sdk/dotnet/TailscaleBastion/Aws/Bastion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,17 @@ public sealed class BastionArgs : global::Pulumi.ResourceArgs
[Input("region", required: true)]
public Input<string> Region { get; set; } = null!;

[Input("routes")]
private InputList<string>? _routes;

/// <summary>
/// The route you'd like to advertise via tailscale.
/// The routes you'd like to advertise via tailscale.
/// </summary>
[Input("route", required: true)]
public Input<string> Route { get; set; } = null!;
public InputList<string> Routes
{
get => _routes ?? (_routes = new InputList<string>());
set => _routes = value;
}

[Input("subnetIds", required: true)]
private InputList<string>? _subnetIds;
Expand Down
11 changes: 4 additions & 7 deletions sdk/go/bastion/aws/bastion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 3 additions & 6 deletions sdk/nodejs/aws/bastion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ export class Bastion extends pulumi.ComponentResource {
if ((!args || args.region === undefined) && !opts.urn) {
throw new Error("Missing required property 'region'");
}
if ((!args || args.route === undefined) && !opts.urn) {
throw new Error("Missing required property 'route'");
}
if ((!args || args.subnetIds === undefined) && !opts.urn) {
throw new Error("Missing required property 'subnetIds'");
}
Expand All @@ -65,7 +62,7 @@ export class Bastion extends pulumi.ComponentResource {
resourceInputs["instanceType"] = args ? args.instanceType : undefined;
resourceInputs["public"] = (args ? args.public : undefined) ?? false;
resourceInputs["region"] = args ? args.region : undefined;
resourceInputs["route"] = args ? args.route : undefined;
resourceInputs["routes"] = args ? args.routes : undefined;
resourceInputs["subnetIds"] = args ? args.subnetIds : undefined;
resourceInputs["tailscaleTags"] = args ? args.tailscaleTags : undefined;
resourceInputs["vpcId"] = args ? args.vpcId : undefined;
Expand Down Expand Up @@ -117,9 +114,9 @@ export interface BastionArgs {
*/
region: pulumi.Input<string>;
/**
* The route you'd like to advertise via tailscale.
* The routes you'd like to advertise via tailscale.
*/
route: pulumi.Input<string>;
routes?: pulumi.Input<pulumi.Input<string>[]>;
/**
* The subnet Ids to launch instances in.
*/
Expand Down
Loading

0 comments on commit 8db73c3

Please sign in to comment.