Skip to content

Instantly share code, notes, and snippets.

@SteveHoggNZ
Created December 2, 2016 00:12
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 SteveHoggNZ/3347bf2ab30f16a29b44c936ebcdd39a to your computer and use it in GitHub Desktop.
Save SteveHoggNZ/3347bf2ab30f16a29b44c936ebcdd39a to your computer and use it in GitHub Desktop.
CloudFormation / Nested stack bastion example
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "EC2 Bastion Server",
"Parameters": {
"VpcId": {
"Type": "AWS::EC2::VPC::Id",
"Description": "The VPC ID"
},
"DeployBastion": {
"Description": "Should a bastion server be deployed?",
"Default": "No",
"Type": "String",
"AllowedValues": ["No", "Yes"]
},
"SubnetId": {
"Description": "The subnet to deploy into",
"Type": "AWS::EC2::Subnet::Id"
}
},
"Conditions" : {
"Deploy" : {"Fn::Equals" : [{"Ref" : "DeployBastion"}, "Yes"]}
},
"Resources": {
"BastionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": {
"Service": [ "ec2.amazonaws.com" ]
},
"Action": [ "sts:AssumeRole" ]
} ]
},
"Path": "/",
"Policies": [ {
"PolicyName": "InvokeLambda",
"PolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "*"
} ]
}
}, {
"PolicyName": "DynamoDBAdmin",
"PolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Action": "dynamodb:*",
"Resource": "*"
} ]
}
} ]
}
},
"BastionInstanceProfile" : {
"Type" : "AWS::IAM::InstanceProfile",
"Properties" : {
"Path" : "/",
"Roles" : [{ "Ref": "BastionRole" }]
}
},
"BastionSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"VpcId": {
"Ref": "VpcId"
},
"SecurityGroupIngress": [{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "<REDACTED>/32"
}],
"Tags": [
{
"Key": "Name",
"Value": "BastionSecurityGroup"
}
],
"GroupDescription": "Allow SSH from my IP"
}
},
"BastionServer": {
"Type" : "AWS::EC2::Instance",
"Condition" : "Deploy",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"yum": {
"mysql": [],
"python27-boto3": []
}
},
"files": {
"/root/.aws/config": {
"content" : { "Fn::Join" : ["", [
"[default]", "\n",
"region=", { "Ref" : "AWS::Region" }, "\n"
]]},
"mode" : "000644",
"owner" : "root",
"group" : "root"
},
"/home/ec2-user/.aws/config": {
"content" : { "Fn::Join" : ["", [
"[default]", "\n",
"region=", { "Ref" : "AWS::Region" }, "\n"
]]},
"mode" : "000644",
"owner" : "ec2-user",
"group" : "ec2-user"
}
}
}
}
},
"Properties": {
"ImageId": "ami-55d4e436",
"InstanceType": "t2.micro",
"KeyName": "DomainsDirectKeyPair",
"NetworkInterfaces": [ {
"AssociatePublicIpAddress": "true",
"DeviceIndex": "0",
"GroupSet": [{ "Ref": "BastionSecurityGroup" }],
"SubnetId": { "Ref": "SubnetId" }
} ],
"IamInstanceProfile": { "Ref": "BastionInstanceProfile" },
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -xe\n",
"yum update -y aws-cfn-bootstrap\n",
"# Install the files and packages from the metadata\n",
"/opt/aws/bin/cfn-init -v ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource BastionServer ",
" --region ", { "Ref" : "AWS::Region" }, "\n"
]]}},
"Tags": [
{
"Key": "Name",
"Value": "BastionServer"
}
]
}
}
},
"Outputs": {
"BastionSecurityGroup": {
"Description": "bastion security group",
"Value": { "Ref": "BastionSecurityGroup" }
},
"PublicIp": {
"Description": "Public IP",
"Value": {
"Fn::If" : [
"Deploy",
{"Fn::GetAtt" : [ "BastionServer", "PublicIp" ]},
{"Ref" : "AWS::NoValue"}
]
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment