Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
vpc_cidr_block = '10.0.0.0/16'
response = vpc.create_vpc(
CidrBlock=vpc_cidr_block,
AmazonProvidedIpv6CidrBlock=False,
DryRun=False,
InstanceTenancy='default'
)
vpcid = response['Vpc']['VpcId']
vpc.modify_vpc_attribute(
EnableDnsHostnames={
'Value': True
},
VpcId=vpcid
)
vpc.modify_vpc_attribute(
EnableDnsSupport={
'Value': True
},
VpcId=vpcid
)
public_cidr = '10.0.1.0/24'
s1 = vpc.create_subnet(
AvailabilityZone='us-east-1a',
CidrBlock=public_cidr,
VpcId=vpcid
)
subnet_public = s1['Subnet']['SubnetId']
s2 = vpc.create_subnet(
AvailabilityZone='us-east-1b',
CidrBlock=private_cidr_1,
VpcId=vpcid
)
subnet_private_1 = s2['Subnet']['SubnetId']
private_cidr_2 = '10.0.3.0/24'
s3 = vpc.create_subnet(
AvailabilityZone='us-east-1c',
CidrBlock=private_cidr_2,
VpcId=vpcid
)
subnet_private_2 = s3['Subnet']['SubnetId']
i1 = vpc.create_internet_gateway()
internet_gateway = i1['InternetGateway']['InternetGatewayId']
i1 = vpc.attach_internet_gateway(
InternetGatewayId=internet_gateway,
VpcId=vpcid
)
print("* Creating route table for public subnet")
default_route = '0.0.0.0/0'
r1 = vpc.create_route_table(
VpcId=vpcid
)
print("* Adding Internet Gateway to route table for a default route")
vpc.create_route(
DestinationCidrBlock=default_route,
RouteTableId=r1['RouteTable']['RouteTableId'],
GatewayId=internet_gateway
)
print("* Creating route table for private subnet")
r2 = vpc.create_route_table(
VpcId=vpcid
)
print("* Associating public and private subnets with their route tables")
vpc.associate_route_table(
RouteTableId=r1['RouteTable']['RouteTableId'],
SubnetId=subnet_public
)
vpc.associate_route_table(
RouteTableId=r2['RouteTable']['RouteTableId'],
SubnetId=subnet_private_1
)
vpc.associate_route_table(
RouteTableId=r2['RouteTable']['RouteTableId'],
SubnetId=subnet_private_2
)
print("* Allowing SSH and HTTPS access from a specific IP")
vpc.authorize_security_group_ingress(
GroupId=sg1,
IpPermissions=[
{
'IpRanges': [
{
'CidrIp': from_ip
},
],
'FromPort': 22,
'ToPort': 22,
'IpProtocol': "tcp"
},
{
'IpRanges': [
{
'CidrIp': from_ip
},
],
'FromPort': 443,
'ToPort': 443,
'IpProtocol': "tcp"
}
]
)
print("* Creating security group for RDS in the private subnet")
response = vpc.create_security_group(
Description='Inbound RDS access',
GroupName='rds_private_subnet',
VpcId=vpcid
)
sg2 = response['GroupId']
from_ip = sg1
print("* Allowing MySQL access from the public subnet in the same VPC")
vpc.authorize_security_group_ingress(
GroupId=sg2,
IpPermissions=[
{
'FromPort': 3306,
'ToPort': 3306,
'IpProtocol': "tcp",
'UserIdGroupPairs': [
{
'VpcId': vpcid,
'GroupId': from_ip
}
]
}
]
)
#
# Launching an EC2 instance in the public subnet
# * https://stackoverflow.com/questions/19029588/how-to-auto-assign-public-ip-to-ec2-instance-with-boto
#
print("* Launching an EC2 instance in the public subnet")
vpc.run_instances(
ImageId='ami-04169656fea786776',
InstanceType='t1.micro',
KeyName='keyname',
MinCount=1,
MaxCount=1,
NetworkInterfaces=[{
'DeviceIndex': 0,
'AssociatePublicIpAddress': True,
'SubnetId': subnet_public,
'Groups': [sg1]
}
]
)
print("* Creating security group for Secrets Manager endpoint in the private subnet")
response = vpc.create_security_group(
Description='Inbound Secrets Manager access',
GroupName='secrets_manager_endpoint',
VpcId=vpcid
)
sg3 = response['GroupId']
from_ip = sg1
print("* Allowing Secrets Manager access from the public subnet in the same VPC")
vpc.authorize_security_group_ingress(
GroupId=sg3,
IpPermissions=[
{
'IpProtocol': "tcp",
'FromPort': 443,
'ToPort': 443,
'UserIdGroupPairs': [
{
'VpcId': vpcid,
'GroupId': from_ip
}
]
}
]
)
#
# Create a VPC endpoint for Secrets Manager inside the VPC you just created attaching the private subnets and
# security groups. Private DNS is true by default and the public endpoint URL can be used.
#
# NOTE: You can also create these for KMS and a few other services if you don't want these calls to be made over the
# Internet.
#
# https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html#what-is-privatelink
#
print("* Creating a private endpoint so all Secrets Manager traffic is inside AWS only")
vpc.create_vpc_endpoint(
VpcEndpointType='Interface',
VpcId=vpcid,
ServiceName='com.amazonaws.us-east-1.secretsmanager',
SubnetIds=[
subnet_private_1,
subnet_private_2
],
SecurityGroupIds=[
sg3
]
)
#
# Load RDS credentials from file on disk. Make sure the file has strong permissions
#
print("* Creating a secret")
with open('mycreds.json') as f:
creds = f.readline()
c = json.loads(creds)
secretname = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(15))
response = sm.create_secret(
Name=secretname,
Description='Credentials to log into the RDS database',
SecretString=creds,
Tags=[
{
'Key': 'RDS',
'Value': 'SecretsManager_RDS'
},
]
)
secret_id = response['ARN']
#
# Not mandatory but maybe you have stuff in an RDS which SecretsManager directly integrates with. To create an RDS
# instance though, you first need an RDS subnet group.
#
# Create a DB subnet group using the subnets that we created a while back
#
print("* Creating a DB subnet group as a pre-requisite for an RDS instance")
response = rds.create_db_subnet_group(
DBSubnetGroupName='rdssecretssubnetgroup',
DBSubnetGroupDescription='Mandatory subnet group for RDS instances',
SubnetIds=[
subnet_private_1,
subnet_private_2
],
Tags=[
{
'Key': 'Name',
'Value': 'Secrets Manager Subnet Group for RDS'
},
]
)
dbsg = response['DBSubnetGroup']['DBSubnetGroupName']
"""
username = 'USER' #Do NOT do this
password = 'PASS' #Do NOT do this
dbname = 'DBNAME' #Do NOT do this
"""
#
# Retrieve secret information from Secrets Manager
#
print("* Retrieving credentials from Secrets Manager for database")
response = sm.get_secret_value(
SecretId=secret_id
)
secret_string = json.loads(response['SecretString'])
username = secret_string['username']
password = secret_string['password']
dbname = secret_string['dbname']
tablename = secret_string['tablename']
#
# Create a DB instance using the VPC, subnet group and security group that we have created earlier in this script.
#
print("* Create an RDS database using all the information we have gathered so far")
rds.create_db_instance(
AllocatedStorage=5,
DBInstanceClass='db.t2.micro',
DBInstanceIdentifier=dbname,
Engine='MySQL',
MasterUsername=username,
MasterUserPassword=password,
DBSubnetGroupName=dbsg,
VpcSecurityGroupIds=[
sg2
]
)
print("* Waiting until RDS metadata is available. This does take a while. So we're going to sleep for 10 minutes to"
"be safe - RDS is slow :|. Please check back after a while :)")
# sleep(600)
# print("* Extracting DB hostname and port from the just created instance to put into Lambda's environment variables")
# response = rds.describe_db_instances(DBInstanceIdentifier='secretsmgrdb')
# hostname = response['DBInstances'][0]['Endpoint']['Address']
# port = response['DBInstances'][0]['Endpoint']['Port']
#
# Hardcoding for testing purposes. Please uncomment the block above if you want this to be fully automatic. Remove
# the following 2 lines as they refer to a host in the testing account.
#
hostname = 'secretsmgrdb.<RANDOMNAME>.us-east-1.rds.amazonaws.com'
port = '3306'
print("* Creating a Lambda function. Waiting for 10 seconds to make sure the role is available")
with open('app.zip', 'rb') as f:
zip_bytes = f.read()
# with open('envvars.json') as f:
# envvars = json.loads(f.read())
sleep(10)
lb.create_function(
FunctionName='hello_world',
Runtime='python3.6',
Role=rolearn,
Handler='app.handler',
Code={
'ZipFile': zip_bytes
},
VpcConfig={
'SubnetIds': [
subnet_private_1,
subnet_private_2
],
'SecurityGroupIds': [
sg4
]
},
Environment={
'Variables': {
'db_name': dbname,
'db_host': hostname,
'db_port': port,
'db_user': username,
'db_password': password,
'table_name': tablename
}
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.