This is the continuation of a AWS Terraform demo to create a VPC in AWS with an EC2 instance connected to MariaDB database running in RDS using a single Terraform plan.
Prerequisites and source code:
EC2 instances are defined using the terraform.tfvars, some values (ami, vpc_security_group_ids, and subnet_id) are derived from modules output so the definition is in the aws_ec2_pro_wp.tf file as terraform.tfvars doesn’t allow interpolation.
#------------------------ # WP PRO #------------------------ aws_ec2_pro_pub_wp_01 = { name = "ditwl-ec2-pro-pub-wp01" ami = "" #Uses data.aws_ami.ubuntu1604.id instance_type = "t2.micro" #AWS Free Tier: 750 hours per month of Linux, RHEL, or SLES t2.micro instance usage availability_zone = "us-east-1a" key_name = "ditwl_kp_infradmin" # vpc_security_group_ids = SEE TF file # subnet_id = SEE TF file associate_public_ip_address = true root_block_device_size = 8 # See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html root_block_device_volume_type = "gp2" tag_private_name = "ditwl-ec2-pro-pub-wp-01" tag_public_name = "www" tag_app = "wp" tag_app_id = "wp-01" tag_os = "ubuntu" tag_os_id = "ubuntu-16" tags_environment = "pro" tag_cost_center = "ditwl-permanent" tags_volume = "ditwl-ec2-pro-pub-wp-01-root" } #------------------------ # WP PRO Security Group #------------------------ aws_sg_ec2_pro_pub_wp_01 = { sec_name = "ditwl-sg-ec2-pro-pub-01" sec_description = "ditwl - WP server access rules - Pub, Env: PRO" allow_all_outbound = false } aws_sr_ec2_pro_pub_wp_01_internet_to_80 = { type = "ingress" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = "0.0.0.0/0" description = "Access from Internet to port 80" } aws_sr_ec2_pro_pub_wp_01_internet_to_443 = { type = "ingress" from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = "0.0.0.0/0" description = "Access from Internet to port 443" }
All EC2 instance names and their Security Rules and Groups follow a standardized naming pattern.
In order to access the created Linux instances in AWS you will need an SSH client. Authentication will use a private key, and in the case of Ubuntu a username named “ubuntu”.
The private key needs to be registered in AWS EC2 console, it can be uploaded to the console or created using a wizard.
Having configured most of the values for the instance in the terraform.tfvars, now the file aws_ec2_pro_wp.tf makes use of Terraform modules to create the resources.
The Terraform module /modules/aws/ec2/instance/add is used to create the EC2 instance. Most of the variables come from the aws_ec2_pro_pub_wp_01 variable definition from terraform.tfvars and the rest are interpolations to other resources:
# Create WP instance module "aws_ec2_pro_pub_wp_01" { source = "./modules/aws/ec2/instance/add" name = var.aws_ec2_pro_pub_wp_01["name"] ami = data.aws_ami.ubuntu1604.id instance_type = var.aws_ec2_pro_pub_wp_01["instance_type"] availability_zone = var.aws_ec2_pro_pub_wp_01["availability_zone"] key_name = var.aws_ec2_pro_pub_wp_01["key_name"] disable_api_termination = var.is_production ? true : false vpc_security_group_ids = [module.aws_sg_ec2_default.id,module.aws_sg_ec2_pro_pub_wp_01.id] subnet_id = module.aws_sn_za_pro_pub_32.id associate_public_ip_address = var.aws_ec2_pro_pub_wp_01["associate_public_ip_address"] instance_tags = {} tag_private_name = var.aws_ec2_pro_pub_wp_01["tag_private_name"] tag_public_name = var.aws_ec2_pro_pub_wp_01["tag_public_name"] tag_app = var.aws_ec2_pro_pub_wp_01["tag_app"] tag_app_id = var.aws_ec2_pro_pub_wp_01["tag_app_id"] tag_os = var.aws_ec2_pro_pub_wp_01["tag_os"] tag_os_id = var.aws_ec2_pro_pub_wp_01["tag_os_id"] tags_environment = var.aws_ec2_pro_pub_wp_01["tags_environment"] tag_cost_center = var.aws_ec2_pro_pub_wp_01["tag_cost_center"] register_dns_private = true route53_private_zone_id = module.aws_route53_public.id register_dns_public = true route53_public_zone_id = module.aws_route53_public.id root_block_device = { volume_size = var.aws_ec2_pro_pub_wp_01["root_block_device_size"] volume_type = var.aws_ec2_pro_pub_wp_01["root_block_device_volume_type"] delete_on_termination = var.is_production ? false : true #If production, Do not delete! } volume_tags = { Name = var.aws_ec2_pro_pub_wp_01["name"] } ignore_changes = ["ami"] }
Securing AWS VPC resources with Terraform makes use of 3 modules:
See AWS Security Groups’ Best Practices.
The following illustration shows the security groups and rules applied to each AWS resource.
Continue the Terraform and Ansible demo, see:
[…] EC2 Instances and Resource Security with Terraform (5/5) […]
[…] It should be unique and follows the Cloud-Resource-Environment-Visibility-Name/ID format (see EC2 Instances and Resource Security for […]