Skip to content

Commit

Permalink
Merge pull request #120 from lbrlabs/features
Browse files Browse the repository at this point in the history
feat(bastion): add support for app connectors, exit nodes, and configurable tags
  • Loading branch information
jaxxstorm committed Mar 15, 2024
2 parents e0e7a02 + efc6fdf commit 6922891
Show file tree
Hide file tree
Showing 13 changed files with 227 additions and 47 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
- dotnet
- go
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
prerequisites:
Expand Down Expand Up @@ -161,7 +161,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
publish:
Expand Down Expand Up @@ -202,7 +202,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
publish_sdk:
Expand Down Expand Up @@ -280,7 +280,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
test:
Expand Down Expand Up @@ -365,7 +365,7 @@ jobs:
- dotnet
- go
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
name: main
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
- dotnet
- go
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
prerequisites:
Expand Down Expand Up @@ -162,7 +162,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
publish:
Expand Down Expand Up @@ -203,7 +203,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
publish_sdk:
Expand Down Expand Up @@ -281,7 +281,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
test:
Expand Down Expand Up @@ -366,7 +366,7 @@ jobs:
- dotnet
- go
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
name: prerelease
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:
- dotnet
- go
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
prerequisites:
Expand Down Expand Up @@ -161,7 +161,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
publish:
Expand Down Expand Up @@ -202,7 +202,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
publish_sdk:
Expand Down Expand Up @@ -280,7 +280,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
test:
Expand Down Expand Up @@ -365,7 +365,7 @@ jobs:
- dotnet
- go
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
name: release
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/run-acceptance-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:
- dotnet
- go
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
comment-notification:
Expand Down Expand Up @@ -187,7 +187,7 @@ jobs:
goversion:
- 1.21.x
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
test:
Expand Down Expand Up @@ -276,7 +276,7 @@ jobs:
- dotnet
- go
nodeversion:
- 18.x
- 21.x
pythonversion:
- "3.7"
name: run-acceptance-tests
Expand Down
86 changes: 58 additions & 28 deletions provider/pkg/provider/aws/bastion.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,31 @@ var (

// The set of arguments for creating a Bastion component resource.
type BastionArgs struct {
VpcID pulumi.StringInput `pulumi:"vpcId"`
SubnetIds pulumi.StringArrayInput `pulumi:"subnetIds"`
TailscaleTags pulumi.StringArrayInput `pulumi:"tailscaleTags"`
Route pulumi.StringInput `pulumi:"route"`
Region pulumi.StringInput `pulumi:"region"`
InstanceType pulumi.StringInput `pulumi:"instanceType"`
HighAvailability bool `pulumi:"highAvailability"`
EnableSSH bool `pulumi:"enableSSH"`
Public bool `pulumi:"public"`
VpcID pulumi.StringInput `pulumi:"vpcId"`
SubnetIds pulumi.StringArrayInput `pulumi:"subnetIds"`
TailscaleTags pulumi.StringArrayInput `pulumi:"tailscaleTags"`
Route pulumi.StringInput `pulumi:"route"`
Region pulumi.StringInput `pulumi:"region"`
InstanceType pulumi.StringInput `pulumi:"instanceType"`
Hostname pulumi.StringInput `pulumi:"hostname"`
HighAvailability bool `pulumi:"highAvailability"`
EnableSSH bool `pulumi:"enableSSH"`
Public bool `pulumi:"public"`
EnableExitNode bool `pulumi:"enableExitNode"`
EnableAppConnector bool `pulumi:"enableAppConnector"`
}

type UserDataArgs struct {
ParameterName string
Route string
Region string
TailscaleTags []string
EnableSSH bool
ParameterName string
Route string
Region string
TailscaleTags string
EnableSSH bool
EnableExitNode bool
EnableAppConnector bool
Hostname string
}

// Join the tags into a CSV
func (uda *UserDataArgs) JoinedTags() string {
return strings.Join(uda.TailscaleTags, ",")
}

// The Bastion component resource.
type Bastion struct {
Expand All @@ -71,21 +73,31 @@ 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),
Preauthorized: pulumi.Bool(true),
Reusable: pulumi.Bool(true),
Tags: args.TailscaleTags,
Description: pulumi.Sprintf("Auth key for %s", hostname),
}, pulumi.Parent(component))
if err != nil {
return nil, fmt.Errorf("error creating tailnet key: %v", err)
}

// store the key in an AWS SSM parameter
tailnetKeySsmParameter, err := ssm.NewParameter(ctx, name, &ssm.ParameterArgs{
Type: ssm.ParameterTypeSecureString,
Value: tailnetKey.Key,
Type: ssm.ParameterTypeSecureString,
Value: tailnetKey.Key,
Description: pulumi.Sprintf("Tailscale auth key for %s", hostname),
}, pulumi.Parent(component))
if err != nil {
return nil, fmt.Errorf("error creating SSM parameter: %v", err)
Expand Down Expand Up @@ -263,14 +275,20 @@ 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).ApplyT(
data := pulumi.All(tailnetKeySsmParameter.Name, args.Route, args.Region, args.TailscaleTags, args.EnableSSH, hostname, args.EnableExitNode, args.EnableAppConnector).ApplyT(
func(args []interface{}) (string, error) {

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

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

var userDataBytes bytes.Buffer
Expand Down Expand Up @@ -309,8 +327,6 @@ func NewBastion(ctx *pulumi.Context,
PublicKey: key.PublicKeyOpenssh,
}, pulumi.Parent(component))



launchConfiguration, err := ec2.NewLaunchConfiguration(ctx, name, &ec2.LaunchConfigurationArgs{
InstanceType: instanceType,
AssociatePublicIpAddress: pulumi.Bool(args.Public),
Expand All @@ -334,13 +350,27 @@ func NewBastion(ctx *pulumi.Context,
size = 1
}

var instanceRefresh autoscaling.GroupInstanceRefreshPtrInput
if args.HighAvailability {
instanceRefresh = autoscaling.GroupInstanceRefreshArgs{
Strategy: pulumi.String("Rolling"),
Preferences: autoscaling.GroupInstanceRefreshPreferencesArgs{
MinHealthyPercentage: pulumi.Int(50),
},
}

} else {
instanceRefresh = nil
}

asg, err := autoscaling.NewGroup(ctx, name, &autoscaling.GroupArgs{
LaunchConfiguration: launchConfiguration.ID(),
MaxSize: pulumi.Int(size),
MinSize: pulumi.Int(size),
HealthCheckType: pulumi.String("EC2"),
HealthCheckGracePeriod: pulumi.Int(30),
VpcZoneIdentifiers: args.SubnetIds,
InstanceRefresh: instanceRefresh,
Tags: autoscaling.GroupTagArray{
autoscaling.GroupTagArgs{
Key: pulumi.String("Name"),
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 --ssh="{{ .EnableSSH }}" --advertise-tags=tag:bastion --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}}" --advertise-routes="{{ .Route }}" --authkey=$(aws ssm get-parameter --name {{.ParameterName}} --region {{.Region}} --with-decryption | jq .Parameter.Value -r) --host-routes
19 changes: 19 additions & 0 deletions schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ description: "A Pulumi package for creating a tailscale bastion in AWS."
repository: "https://github.com/lbrlabs/pulumi-tailscale-bastion"
publisher: "lbrlabs"
displayname: "tailscale-bastion"
keywords:
- aws
- tailscale
- lbrlabs
- kind/component
- category/network
resources:
tailscale-bastion:azure:Bastion:
isComponent: true
Expand Down Expand Up @@ -58,6 +64,9 @@ resources:
tailscale-bastion:aws:Bastion:
isComponent: true
inputProperties:
hostname:
type: string
description: "The hostname of the bastion."
public:
type: boolean
description: "Whether the bastion is going in public subnets."
Expand All @@ -66,6 +75,14 @@ resources:
type: boolean
description: "Whether to enable SSH access to the bastion."
default: true
enableAppConnector:
type: boolean
description: "Whether the bastion advertises itself as an app connector."
default: false
enableExitNode:
type: boolean
description: "Whether the subnet router can advertise itself as an exit node."
default: false
highAvailability:
type: boolean
description: "Whether the bastion should be highly available."
Expand Down Expand Up @@ -166,6 +183,8 @@ language:
"@pulumi/tailscale": "^0.11.0"
devDependencies:
typescript: "^3.7.0"
glob: "^9.0.0"
minimatch: "^5.0.0"
packageName: "@lbrlabs/pulumi-tailscalebastion"
python:
packageName: "lbrlabs_pulumi_tailscalebastion"
Expand Down
Loading

0 comments on commit 6922891

Please sign in to comment.