Skip to content

Instantly share code, notes, and snippets.

@jen20
Created August 7, 2018 20:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jen20/730e392f8d8361f02f494b294f62d66c to your computer and use it in GitHub Desktop.
Save jen20/730e392f8d8361f02f494b294f62d66c to your computer and use it in GitHub Desktop.
/*
* Copyright 2018, James Nugent.
*
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*/
import * as aws from "@pulumi/aws";
import { ComponentResource, Output, ResourceOptions } from "@pulumi/pulumi";
export interface BastionHostInputs {
description: string;
baseTags: aws.Tags;
imageId?: string;
imageNameRegex?: string;
imageOwner?: string;
subnetId: Output<string>;
keyName: Output<string>;
authorizeSSHFrom?: Output<string>[];
additionalSecurityGroupIds: Output<string>[];
instanceType?: aws.ec2.InstanceType;
instanceProfileId?: Output<string>;
}
export interface BastionHostOutputs {
instanceId: Output<string>;
publicIpAddress: Output<string>;
}
export class BastionHost extends ComponentResource implements BastionHostOutputs {
public publicIpAddress: Output<string>;
public instanceId: Output<string>;
public static async create(name: string, inputs: BastionHostInputs,
opts?: ResourceOptions): Promise<BastionHost> {
const instance = new BastionHost(`${name}-bastion-host`, inputs, opts);
const instanceParent = {parent: instance};
const baseName = name.toLowerCase();
const vpcId = await inputs.subnetId.apply((subnetId) => {
return aws.ec2.getSubnet({
id: subnetId,
}).then(r => r.vpcId);
});
let ami = "";
if (inputs.imageId) {
ami = inputs.imageId;
} else {
const amazonLinux2NameRegex = "amzn2-ami-hvm-2*-x86_64-gp2";
const owners: string[] = [];
if (inputs.imageOwner) {
owners.push(inputs.imageOwner);
}
ami = (await aws.getAmi({
nameRegex: inputs.imageNameRegex || amazonLinux2NameRegex,
owners: owners,
})).id;
}
const ingressSecurityGroup = new aws.ec2.SecurityGroup(`${baseName}-bastion-sg`, {
description: `${inputs.description} Bastion Ingress`,
vpcId: vpcId,
ingress: [{
description: "SSH Traffic",
fromPort: 22,
toPort: 22,
protocol: "TCP",
cidrBlocks: inputs.authorizeSSHFrom || ["0.0.0.0/0"],
}],
egress: [{
description: "All Egress Traffic",
fromPort: 0,
toPort: 0,
protocol: "-1",
cidrBlocks: ["0.0.0.0/0"],
}],
}, instanceParent);
const securityGroupIds: Output<string>[] = [ingressSecurityGroup.id];
securityGroupIds.push(...inputs.additionalSecurityGroupIds);
const bastionTags = Object.assign({
Name: `${inputs.description} Bastion Host`,
}, inputs.baseTags);
const bastion = new aws.ec2.Instance(`${baseName}-bastion-instance`, {
subnetId: inputs.subnetId,
vpcSecurityGroupIds: securityGroupIds,
ami: ami,
keyName: inputs.keyName,
instanceType: inputs.instanceType || aws.ec2.T2InstanceMicro,
iamInstanceProfile: inputs.instanceProfileId || undefined,
tags: bastionTags,
}, instanceParent);
instance.instanceId = bastion.id;
instance.publicIpAddress = bastion.publicIp;
return instance;
}
private constructor(name: string, inputs: BastionHostInputs, opts?: ResourceOptions) {
super("operator-error:aws:vault:BastionHost", name, inputs, opts);
this.registerOutputs({
publicIpAddress: this.publicIpAddress,
instanceId: this.instanceId,
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment