├── 2. VPC Reference Architecture.jpg ├── README.md ├── acm reference.tf ├── acm reference.yml ├── backend reference.tf ├── ec2-reference.tf ├── iam-reference.tf ├── jenkins-reference.tf ├── nat gateway reference.tf ├── rds-refference.tf ├── security-group reference.tf └── vpc reference.tf /2. VPC Reference Architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azeezsalu/terraform-tutorial-reference-files/62b8e87fa0845f98608922fbda3bcb5e9321722d/2. VPC Reference Architecture.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terraform-tutorial-reference-files -------------------------------------------------------------------------------- /acm reference.tf: -------------------------------------------------------------------------------- 1 | # configured aws provider with proper credentials 2 | provider "aws" { 3 | region = 4 | profile = 5 | } 6 | 7 | # request public certificates from the amazon certificate manager. 8 | resource "aws_acm_certificate" "acm_certificate" { 9 | domain_name = 10 | subject_alternative_names = [] 11 | validation_method = 12 | 13 | lifecycle { 14 | create_before_destroy = 15 | } 16 | } 17 | 18 | # get details about a route 53 hosted zone 19 | data "aws_route53_zone" "route53_zone" { 20 | name = 21 | private_zone = 22 | } 23 | 24 | # create a record set in route 53 for domain validatation 25 | resource "aws_route53_record" "route53_record" { 26 | for_each = { 27 | for dvo in *aws_acm_certificate.acm_certificate*.domain_validation_options : dvo.domain_name => { 28 | name = dvo.resource_record_name 29 | record = dvo.resource_record_value 30 | type = dvo.resource_record_type 31 | } 32 | } 33 | 34 | allow_overwrite = true 35 | name = each.value.name 36 | records = [each.value.record] 37 | ttl = 60 38 | type = each.value.type 39 | zone_id = 40 | } 41 | 42 | # validate acm certificates 43 | resource "aws_acm_certificate_validation" "acm_certificate_validation" { 44 | certificate_arn = 45 | validation_record_fqdns = [for record in *aws_route53_record.route53_record* : record.fqdn] 46 | } -------------------------------------------------------------------------------- /acm reference.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Resources: 3 | AwsAcmCertificate: 4 | Type: AWS::CertificateManager::Certificate 5 | Properties: 6 | DomainName: 7 | DomainValidationOptions: 8 | - DomainName: 9 | HostedZoneId: 10 | SubjectAlternativeNames: 11 | - 12 | ValidationMethod: -------------------------------------------------------------------------------- /backend reference.tf: -------------------------------------------------------------------------------- 1 | # store the terraform state file in s3 2 | terraform { 3 | backend "s3" { 4 | bucket = 5 | key = 6 | region = 7 | profile = 8 | } 9 | } -------------------------------------------------------------------------------- /ec2-reference.tf: -------------------------------------------------------------------------------- 1 | # configured aws provider with proper credentials 2 | provider "aws" { 3 | region = 4 | profile = 5 | } 6 | 7 | 8 | # create default vpc if one does not exit 9 | resource "aws_default_vpc" "default_vpc" { 10 | 11 | tags = { 12 | Name = 13 | } 14 | } 15 | 16 | 17 | # use data source to get all avalablility zones in region 18 | data "aws_availability_zones" "available_zones" {} 19 | 20 | 21 | # create default subnet if one does not exit 22 | resource "aws_default_subnet" "default_az1" { 23 | availability_zone = 24 | 25 | tags = { 26 | Name = 27 | } 28 | } 29 | 30 | 31 | # create security group for the ec2 instance 32 | resource "aws_security_group" "ec2_security_group" { 33 | name = "ec2 security group" 34 | description = "allow access on ports 80 and 22" 35 | vpc_id = 36 | 37 | ingress { 38 | description = "http access" 39 | from_port = 40 | to_port = 41 | protocol = 42 | cidr_blocks = 43 | } 44 | 45 | ingress { 46 | description = "ssh access" 47 | from_port = 48 | to_port = 49 | protocol = 50 | cidr_blocks = 51 | } 52 | 53 | egress { 54 | from_port = 55 | to_port = 56 | protocol = 57 | cidr_blocks = 58 | } 59 | 60 | tags = { 61 | Name = 62 | } 63 | } 64 | 65 | 66 | # use data source to get a registered amazon linux 2 ami 67 | data "aws_ami" "amazon_linux_2" { 68 | most_recent = true 69 | owners = ["amazon"] 70 | 71 | filter { 72 | name = "owner-alias" 73 | values = ["amazon"] 74 | } 75 | 76 | filter { 77 | name = "name" 78 | values = ["amzn2-ami-hvm*"] 79 | } 80 | } 81 | 82 | 83 | # launch the ec2 instance and install website 84 | resource "aws_instance" "ec2_instance" { 85 | ami = 86 | instance_type = 87 | subnet_id = 88 | vpc_security_group_ids = 89 | key_name = 90 | user_data = 91 | 92 | tags = { 93 | Name = 94 | } 95 | } 96 | 97 | 98 | # print the ec2's public ipv4 address 99 | output "public_ipv4_address" { 100 | value = 101 | } -------------------------------------------------------------------------------- /iam-reference.tf: -------------------------------------------------------------------------------- 1 | # configured aws provider with proper credentials 2 | provider "aws" { 3 | region = 4 | profile = 5 | } 6 | 7 | # create an iam user 8 | resource "aws_iam_user" "iam_user" { 9 | name = 10 | } 11 | 12 | # give the iam user programatic access 13 | resource "aws_iam_access_key" "iam_access_key" { 14 | user = 15 | } 16 | 17 | # create the inline policy 18 | data "aws_iam_policy_document" "s3_get_put_detele_policy_document" { 19 | statement { 20 | actions = [ 21 | ] 22 | 23 | resources = [ 24 | ] 25 | } 26 | } 27 | 28 | # attach the policy to the user 29 | resource "aws_iam_user_policy" "s3_get_put_detele_policy" { 30 | name = 31 | user = 32 | policy = 33 | } -------------------------------------------------------------------------------- /jenkins-reference.tf: -------------------------------------------------------------------------------- 1 | # configured aws provider with proper credentials 2 | provider "aws" { 3 | region = "us-east-1" 4 | profile = "terraform-user" 5 | } 6 | 7 | 8 | # create default vpc if one does not exit 9 | resource "aws_default_vpc" "default_vpc" { 10 | 11 | tags = { 12 | Name = "default vpc" 13 | } 14 | } 15 | 16 | 17 | # use data source to get all avalablility zones in region 18 | data "aws_availability_zones" "available_zones" {} 19 | 20 | 21 | # create default subnet if one does not exit 22 | resource "aws_default_subnet" "default_az1" { 23 | availability_zone = data.aws_availability_zones.available_zones.names[0] 24 | 25 | tags = { 26 | Name = "default subnet" 27 | } 28 | } 29 | 30 | 31 | # create security group for the ec2 instance 32 | resource "aws_security_group" "ec2_security_group" { 33 | name = "ec2 security group" 34 | description = "allow access on ports 8080 and 22" 35 | vpc_id = 36 | 37 | # allow access on port 8080 38 | ingress { 39 | description = "http proxy access" 40 | from_port = 41 | to_port = 42 | protocol = 43 | cidr_blocks = 44 | } 45 | 46 | # allow access on port 22 47 | ingress { 48 | description = "ssh access" 49 | from_port = 50 | to_port = 51 | protocol = 52 | cidr_blocks = 53 | } 54 | 55 | egress { 56 | from_port = 57 | to_port = 58 | protocol = 59 | cidr_blocks = 60 | } 61 | 62 | tags = { 63 | Name = "jenkins server security group" 64 | } 65 | } 66 | 67 | 68 | # use data source to get a registered amazon linux 2 ami 69 | data "aws_ami" "amazon_linux_2" { 70 | most_recent = true 71 | owners = ["amazon"] 72 | 73 | filter { 74 | name = "owner-alias" 75 | values = ["amazon"] 76 | } 77 | 78 | filter { 79 | name = "name" 80 | values = ["amzn2-ami-hvm*"] 81 | } 82 | } 83 | 84 | 85 | # launch the ec2 instance and install website 86 | resource "aws_instance" "ec2_instance" { 87 | ami = 88 | instance_type = 89 | subnet_id = 90 | vpc_security_group_ids = 91 | key_name = 92 | # user_data = file("install_jenkins.sh") 93 | 94 | tags = { 95 | Name = 96 | } 97 | } 98 | 99 | 100 | # an empty resource block 101 | resource "null_resource" "name" { 102 | 103 | # ssh into the ec2 instance 104 | connection { 105 | type = 106 | user = 107 | private_key = file() 108 | host = 109 | } 110 | 111 | # copy the install_jenkins.sh file from your computer to the ec2 instance 112 | provisioner "file" { 113 | source = 114 | destination = 115 | } 116 | 117 | # set permissions and run the install_jenkins.sh file 118 | provisioner "remote-exec" { 119 | inline = [ 120 | ] 121 | } 122 | 123 | # wait for ec2 to be created 124 | depends_on = [] 125 | } 126 | 127 | 128 | # print the url of the jenkins server 129 | output "website_url" { 130 | value = join ("", ["http://", aws_instance.ec2_instance.public_dns, ":", "8080"]) 131 | } -------------------------------------------------------------------------------- /nat gateway reference.tf: -------------------------------------------------------------------------------- 1 | # allocate elastic ip. this eip will be used for the nat-gateway in the public subnet az1 2 | resource "aws_eip" "eip_for_nat_gateway_az1" { 3 | vpc = 4 | 5 | tags = { 6 | Name = 7 | } 8 | } 9 | 10 | # allocate elastic ip. this eip will be used for the nat-gateway in the public subnet az2 11 | resource "aws_eip" "eip_for_nat_gateway_az2" { 12 | vpc = 13 | 14 | tags = { 15 | Name = 16 | } 17 | } 18 | 19 | # create nat gateway in public subnet az1 20 | resource "aws_nat_gateway" "nat_gateway_az1" { 21 | allocation_id = 22 | subnet_id = 23 | 24 | tags = { 25 | Name = 26 | } 27 | 28 | # to ensure proper ordering, it is recommended to add an explicit dependency 29 | depends_on = 30 | } 31 | 32 | # create nat gateway in public subnet az2 33 | resource "aws_nat_gateway" "nat_gateway_az2" { 34 | allocation_id = 35 | subnet_id = 36 | 37 | tags = { 38 | Name = 39 | } 40 | 41 | # to ensure proper ordering, it is recommended to add an explicit dependency 42 | # on the internet gateway for the vpc. 43 | depends_on = 44 | } 45 | 46 | # create private route table az1 and add route through nat gateway az1 47 | resource "aws_route_table" "private_route_table_az1" { 48 | vpc_id = 49 | 50 | route { 51 | cidr_block = 52 | nat_gateway_id = 53 | } 54 | 55 | tags = { 56 | Name = 57 | } 58 | } 59 | 60 | # associate private app subnet az1 with private route table az1 61 | resource "aws_route_table_association" "private_app_subnet_az1_route_table_az1_association" { 62 | subnet_id = 63 | route_table_id = 64 | } 65 | 66 | # associate private data subnet az1 with private route table az1 67 | resource "aws_route_table_association" "private_data_subnet_az1_route_table_az1_association" { 68 | subnet_id = 69 | route_table_id = 70 | } 71 | 72 | # create private route table az2 and add route through nat gateway az2 73 | resource "aws_route_table" "private_route_table_az2" { 74 | vpc_id = 75 | 76 | route { 77 | cidr_block = 78 | nat_gateway_id = 79 | } 80 | 81 | tags = { 82 | Name = 83 | } 84 | } 85 | 86 | # associate private app subnet az2 with private route table az2 87 | resource "aws_route_table_association" "private_app_subnet_az2_route_table_az2_association" { 88 | subnet_id = 89 | route_table_id = 90 | } 91 | 92 | # associate private data subnet az2 with private route table az2 93 | resource "aws_route_table_association" "private_data_subnet_az2_route_table_az2_association" { 94 | subnet_id = 95 | route_table_id = 96 | } -------------------------------------------------------------------------------- /rds-refference.tf: -------------------------------------------------------------------------------- 1 | # configured aws provider with proper credentials 2 | provider "aws" { 3 | region = 4 | profile = 5 | } 6 | 7 | 8 | # create default vpc if one does not exit 9 | resource "aws_default_vpc" "default_vpc" { 10 | 11 | tags = { 12 | Name = "default vpc" 13 | } 14 | } 15 | 16 | 17 | # use data source to get all avalablility zones in region 18 | data "aws_availability_zones" "available_zones" {} 19 | 20 | 21 | # create a default subnet in the first az if one does not exit 22 | resource "aws_default_subnet" "subnet_az1" { 23 | availability_zone = 24 | } 25 | 26 | # create a default subnet in the second az if one does not exit 27 | resource "aws_default_subnet" "subnet_az2" { 28 | availability_zone = 29 | } 30 | 31 | # create security group for the web server 32 | resource "aws_security_group" "webserver_security_group" { 33 | name = "webserver security group" 34 | description = "enable http access on port 80" 35 | vpc_id = 36 | 37 | ingress { 38 | description = "http access" 39 | from_port = 40 | to_port = 41 | protocol = 42 | cidr_blocks = 43 | } 44 | 45 | egress { 46 | from_port = 47 | to_port = 48 | protocol = 49 | cidr_blocks = 50 | } 51 | 52 | tags = { 53 | Name = 54 | } 55 | } 56 | 57 | # create security group for the database 58 | resource "aws_security_group" "database_security_group" { 59 | name = "database security group" 60 | description = "enable mysql/aurora access on port 3306" 61 | vpc_id = 62 | 63 | ingress { 64 | description = "mysql/aurora access" 65 | from_port = 66 | to_port = 67 | protocol = 68 | security_groups = 69 | } 70 | 71 | egress { 72 | from_port = 73 | to_port = 74 | protocol = 75 | cidr_blocks = 76 | } 77 | 78 | tags = { 79 | Name = 80 | } 81 | } 82 | 83 | 84 | # create the subnet group for the rds instance 85 | resource "aws_db_subnet_group" "database_subnet_group" { 86 | name = 87 | subnet_ids = 88 | description = 89 | 90 | tags = { 91 | Name = 92 | } 93 | } 94 | 95 | 96 | # create the rds instance 97 | resource "aws_db_instance" "db_instance" { 98 | engine = 99 | engine_version = 100 | multi_az = 101 | identifier = 102 | username = 103 | password = 104 | instance_class = 105 | allocated_storage = 106 | db_subnet_group_name = 107 | vpc_security_group_ids = 108 | availability_zone = 109 | db_name = 110 | skip_final_snapshot = 111 | } 112 | -------------------------------------------------------------------------------- /security-group reference.tf: -------------------------------------------------------------------------------- 1 | # create security group for the application load balancer 2 | resource "aws_security_group" "alb_security_group" { 3 | name = "alb security group" 4 | description = "enable http/https access on port 80/443" 5 | vpc_id = 6 | 7 | ingress { 8 | description = "http access" 9 | from_port = 10 | to_port = 11 | protocol = 12 | cidr_blocks = 13 | } 14 | 15 | ingress { 16 | description = "https access" 17 | from_port = 18 | to_port = 19 | protocol = 20 | cidr_blocks = 21 | } 22 | 23 | egress { 24 | from_port = 25 | to_port = 26 | protocol = 27 | cidr_blocks = 28 | } 29 | 30 | tags = { 31 | Name = 32 | } 33 | } 34 | 35 | # create security group for the container 36 | resource "aws_security_group" "ecs_security_group" { 37 | name = "ecs security group" 38 | description = "enable http/https access on port 80/443 via alb sg" 39 | vpc_id = 40 | 41 | ingress { 42 | description = "http access" 43 | from_port = 44 | to_port = 45 | protocol = 46 | security_groups = 47 | } 48 | 49 | ingress { 50 | description = "https access" 51 | from_port = 52 | to_port = 53 | protocol = 54 | security_groups = 55 | } 56 | 57 | egress { 58 | from_port = 59 | to_port = 60 | protocol = 61 | cidr_blocks = 62 | } 63 | 64 | tags = { 65 | Name = 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /vpc reference.tf: -------------------------------------------------------------------------------- 1 | # create vpc 2 | resource "aws_vpc" "vpc" { 3 | cidr_block = 4 | instance_tenancy = 5 | enable_dns_hostnames = true 6 | 7 | tags = { 8 | Name = "${}-vpc" 9 | } 10 | } 11 | 12 | # create internet gateway and attach it to vpc 13 | resource "aws_internet_gateway" "internet_gateway" { 14 | vpc_id = 15 | 16 | tags = { 17 | Name = "${}-igw" 18 | } 19 | } 20 | 21 | # use data source to get all avalablility zones in region 22 | data "aws_availability_zones" "available_zones" {} 23 | 24 | # create public subnet az1 25 | resource "aws_subnet" "public_subnet_az1" { 26 | vpc_id = 27 | cidr_block = 28 | availability_zone = 29 | map_public_ip_on_launch = 30 | 31 | tags = { 32 | Name = 33 | } 34 | } 35 | 36 | # create public subnet az2 37 | resource "aws_subnet" "public_subnet_az2" { 38 | vpc_id = 39 | cidr_block = 40 | availability_zone = 41 | map_public_ip_on_launch = 42 | 43 | tags = { 44 | Name = 45 | } 46 | } 47 | 48 | # create route table and add public route 49 | resource "aws_route_table" "public_route_table" { 50 | vpc_id = 51 | 52 | route { 53 | cidr_block = 54 | gateway_id = 55 | } 56 | 57 | tags = { 58 | Name = 59 | } 60 | } 61 | 62 | # associate public subnet az1 to "public route table" 63 | resource "aws_route_table_association" "public_subnet_az1_route_table_association" { 64 | subnet_id = 65 | route_table_id = 66 | } 67 | 68 | # associate public subnet az2 to "public route table" 69 | resource "aws_route_table_association" "public_subnet_az2_route_table_association" { 70 | subnet_id = 71 | route_table_id = 72 | } 73 | 74 | # create private app subnet az1 75 | resource "aws_subnet" "private_app_subnet_az1" { 76 | vpc_id = 77 | cidr_block = 78 | availability_zone = 79 | map_public_ip_on_launch = 80 | 81 | tags = { 82 | Name = 83 | } 84 | } 85 | 86 | # create private app subnet az2 87 | resource "aws_subnet" "private_app_subnet_az2" { 88 | vpc_id = 89 | cidr_block = 90 | availability_zone = 91 | map_public_ip_on_launch = 92 | 93 | tags = { 94 | Name = 95 | } 96 | } 97 | 98 | # create private data subnet az1 99 | resource "aws_subnet" "private_data_subnet_az1" { 100 | vpc_id = 101 | cidr_block = 102 | availability_zone = 103 | map_public_ip_on_launch = 104 | 105 | tags = { 106 | Name = 107 | } 108 | } 109 | 110 | # create private data subnet az2 111 | resource "aws_subnet" "private_data_subnet_az2" { 112 | vpc_id = 113 | cidr_block = 114 | availability_zone = 115 | map_public_ip_on_launch = 116 | 117 | tags = { 118 | Name = 119 | } 120 | } --------------------------------------------------------------------------------