Skip to content

Instantly share code, notes, and snippets.

@thomaspoignant
Last active March 8, 2021 11:45
Create a Bastion using AWS CDK
from aws_cdk import (
core,
)
from aws_cdk.aws_ec2 import BastionHostLinux, InstanceType, AmazonLinuxImage, \
SubnetSelection, SecurityGroup, SubnetType
from network import Vpc
class Bastion(core.Construct):
security_group: SecurityGroup
def __init__(self, scope: core.Construct, id: str) -> None:
super().__init__(scope, id)
vpc = Vpc.from_vpc_attributes(self, 'VPC', vpc_id='vpc-XXX')
self.security_group = self.__create_security_group(vpc)
bastion = BastionHostLinux(
self, id,
vpc=vpc,
instance_name='my-bastion',
instance_type=InstanceType('t3.micro'),
machine_image=AmazonLinuxImage(),
subnet_selection=SubnetSelection(subnet_type=SubnetType.PUBLIC),
security_group=self.security_group
)
core.CfnOutput(self, 'my-bastion-id', value=bastion.instance_id)
def __create_security_group(self, vpc: Vpc) -> SecurityGroup:
return SecurityGroup(
scope=self,
id='bastion-sg',
security_group_name='bastion-sg',
description='Security group for the bastion, no inbound open because we should access'
' to the bastion via AWS SSM',
vpc=vpc,
allow_all_outbound=True
)
@neilkuan
Copy link

neilkuan commented Oct 29, 2020

your medium blog is amazing.
but maybe you can use CfnOutput return InstanceId 😊

    def __init__(self, scope: core.Construct, id: str) -> None:
        super().__init__(scope, id)

        vpc = Vpc.from_vpc_attributes(self, 'VPC', vpc_id='vpc-XXX')
        self.security_group = self.__create_security_group(vpc)

        bastion = BastionHostLinux(
            self, id,
            vpc=vpc,
            instance_name='my-bastion',
            instance_type=InstanceType('t3.micro'),
            machine_image=AmazonLinuxImage(),
            subnet_selection=SubnetSelection(subnet_type=SubnetType.PUBLIC),
            security_group=self.security_group
        )
       core.CfnOutput(self, 'instance-id', value=bastion.instance_id)

@thomaspoignant
Copy link
Author

@guan840912 yes you are right it can be great to have output here.
I've added it and I will update the blog post to explain it.

@cipriancaba
Copy link

I just tried this and it wasn't working. AmazonLinuxImage was defaulting to first gen that didn't have ec2-instance-connect working. If anyone hits this problem, just update the macine_image to

machine_image=MachineImage.latest_amazon_linux(
            generation=AmazonLinuxGeneration.AMAZON_LINUX_2,
            edition=AmazonLinuxEdition.STANDARD,
        )

@thomaspoignant
Copy link
Author

I just tried this and it wasn't working. AmazonLinuxImage was defaulting to first gen that didn't have ec2-instance-connect working. If anyone hits this problem, just update the macine_image to

machine_image=MachineImage.latest_amazon_linux(
            generation=AmazonLinuxGeneration.AMAZON_LINUX_2,
            edition=AmazonLinuxEdition.STANDARD,
        )

Good catch @cipriancaba, I just wonder what happens when a new Amazon linux is released? Does it destroy/recreate the bastion?

@cipriancaba
Copy link

That's exactly what happens, everything should just work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment