diff --git a/README.md b/README.md index bcc8986..aca4b4c 100644 --- a/README.md +++ b/README.md @@ -2,143 +2,106 @@ ## Basic Information -This terraform module can be used to create an application-cluster consisting of -+ ApplicationLoadBalancer - + 1 Listener for Port 80 - + 1 Listener for Port 443 (An AWS-certificate is mandatory for this at the moment) -+ AutoScaling-Group -+ IAM-Instance-Profile -+ LaunchConfiguration -+ TargetGroup +This terraform module consists of two submodules. One for the loadbalancer and +one for the application-cluster. -## Usage -### Parameters -```hcl-terraform -variable "application_cluster_lb_security_groups" { - description = "security-groups which should be assigned to the lb" - type = "list" -} - -variable "application_cluster_lb_access_log_bucket" { - description = "the bucket name to save the lb-access-logs to. The application-data-bucket of all accounts is configured for log-file-access" -} - -variable "application_cluster_lb_access_log_folder" { - description = "the folder where the logs should be saved. The application-data-bucket of all accounts is configured with the default path" - default = "logs/access" -} - -variable "application_cluster_access_log_enabled" { - description = "enable/disable the logging of access (default: true)" - default = true -} - -variable "application_cluster_loadbalancer_type" { - description = "which lb type to use: application or network (default: application)" - default = "application" - type = "string" -} - -variable "application_cluster_ssl_cert_arn" { - description = "The ssl-certificate for the lb" - default = "" -} - -# Appserver - Cluster -variable "application_cluster_ami_id" { - description = "the AMI with which the app-servers should be created" -} - -variable "application_cluster_application_name" { - description = "the name of the application beeing build" -} - -variable "application_cluster_environment" { - description = "the environement of the cluster, e.g. stage or live" -} - -variable "application_cluster_instance_port_http" { - default = 80 - description = "the port for http on the instances" -} - -variable "application_cluster_instance_role_id" { - description = "the instance-role to attach to the appservers" - default = "" -} +This separation is useful to be able to have 1 loadbalancer with 1 or more +application-cluster in different code bases! -variable "application_cluster_instance_type" { - description = "the size of the instances, e.g. t2.micro" -} +1. LoadBalancer -variable "application_cluster_max_size" { - default = 1 - description = "defines the max-value of the autoscaling group" -} -variable "application_cluster_min_size" { - default = 1 - description = "defineds the min-value for the autoscaling group" -} +Resources for a LoadBalancer (default: ApplicationLoadBalancer) with + 1 Listener for Port 80 + 1 Listener for Port 443 (An AWS-certificate is mandatory for this at the moment) + 1 Default Target Group (needed to define a listener) + +2. ApplicationCluster -variable "application_cluster_propagate_at_launch" { - default = true -} +Resources for an auto scaling group application cluster + + AutoScaling-Group + + IAM-Instance-Profile + + LaunchConfiguration + + TargetGroup + + 1 Listener rule to attach it to a loadbalancer listener + + 1 Listener SSL rule to attach it to a loadbalancer ssl listener -variable "application_cluster_security_groups" { - description = "Security-Groups to append to the instances" - type = "list" -} +## Usage +### Loadbalancer +#### Variables +- `application_cluster_lb_security_groups`: (list) Security groups which should be assigned to the loadbalancer +- `application_cluster_lb_access_log_bucket`: (string) The bucket name to save the lb-access-logs to. +- `application_cluster_lb_access_log_folder`: (string) The folder where the logs should be saved. +- `application_cluster_access_log_enabled`: (boolean|default:true) Enable/disable the logging of access. +- `application_cluster_loadbalancer_type`: (string|default:application) Which lb type to use: application or network. +- `application_cluster_ssl_cert_arn`: (string) The ssl-certificate for the loadbalancer. +- `application_cluster_application_name`: (string) The name to identify the loadbalancer. +- `application_cluster_environment`: (string) The environment of the loadbalancer. +- `application_cluster_instance_port_http`: (int|default:80) The port for http communication with an instance. +- `application_cluster_subnet_ids`: (list) Subnet ids to assign to the loadbalancer +- `application_cluster_vpc_id`: (string) VPC to work with. +- `application_cluster_ssl_policy`: (string|default:ELBSecurityPolicy-TLS-1-2-2017-01) Policy to use for SSL. + +### Application-Cluster +#### Variables +- `application_cluster_ami_id`: (string) The AMI with which the app-servers should be created. +- `application_cluster_instance_type`: (string) The size of an instance, e.g. t2.micro. +- `application_cluster_launch_configuration_security_groups`: (list) Security groups which should be assigned to an instance. +- `application_cluster_launch_configuration_detailed_monitoring`: (boolean|default:false) You can find information about detailed_monitoring in the [AWS Documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-cloudwatch-new.html). +- `application_cluster_user_data`: (string) Custom start-up script in base64-style. +- `application_cluster_instance_role_id`: (string) The instance-role to attach to an instance. +- `application_cluster_application_name`: (string) The name to identify an instance. +- `application_cluster_environment`: (string) The environment of an instance. +- `application_cluster_instance_port_http`: (int|default:80) The port for http communication with an instance. +- `application_cluster_max_size`: (int|default:1) Defines the max-value of the autoscaling group. +- `application_cluster_min_size`: (int|default:1) Defines the min-value of the autoscaling group. +- `application_cluster_subnet_ids`: (list) Subnet ids to assign to an instance. +- `application_cluster_vpc_id`: (string) VPC to work with. +- `application_cluster_propagate_at_launch`: (bool|default:true) +- `loadbalancer_listener_arn`: (string) ARN of a loadbalancer listener to be able to attach a target group. +- `loadbalancer_listener_ssl_arn`: (string) ARN of a loadbalancer ssl listener to be able to attach a target group. +- `application_cluster_listener_rule_condition_field`: (string) Field on which the listener rule condition should be triggered. More in the [AWS Documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_RuleCondition.html)! +- `application_cluster_listener_rule_condition_values`: (list) Values which should be used on listener rule condition. More in the [AWS Documentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticloadbalancingv2-listenerrule-conditions.html) -variable "application_cluster_subnet_ids" { - type = "list" -} -variable "application_cluster_vpc_id" { - description = "vpc to attach target groups to" - type = "string" -} +### Using the Module +```hcl-terraform +module "loadbalancer" { + source = "git::ssh://git@github.com/solutionDrive/terraform-aws-application-cluster.git//loadbalancer" -variable "application_cluster_user_data" { - description = "Custom start-up script in base64-style" - default = "" + application_cluster_lb_security_groups = ["List", "of", "SecurityGroupIDs"] + application_cluster_lb_access_log_bucket = "bucket-name-for-logging" + application_cluster_ssl_cert_arn = "${data.aws_acm_certificate.certificate.arn}" + application_cluster_application_name = "AwesomeLoadbalancer" + application_cluster_environment = "stage" + application_cluster_subnet_ids = ["List", "of", "SubnetIds"] + application_cluster_vpc_id = "your-vpc-id" } -variable "application_cluster_ssl_policy" { - description = "Policy for SSL" - default = "ELBSecurityPolicy-TLS-1-2-2017-01" +data "aws_acm_certificate" "certificate" { + domain = "your-awsome-domain.tld" + statuses = ["ISSUED"] } ``` - variable "application_cluster_launch_configuration_detailed_monitoring" { - description = "Enable/disable detailed monitoring" - default = false - } -You can find information about detailed_monitoring in the [AWS Documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-cloudwatch-new.html) - -### Using the Module ```hcl-terraform module "application_cluster" { - source = "git::ssh://git@github.com/solutionDrive/terraform-aws-application-cluster" - - application_cluster_instance_type = "t2.micro" - application_cluster_lb_security_groups = ["List", "of", "SecurityGroupIDs"] + source = "git::ssh://git@github.com/solutionDrive/terraform-aws-application-cluster.git//application_cluster" + application_cluster_ami_id = "${data.aws_ami.appserver.id}" - application_cluster_application_name = "AwsomeApplication" + application_cluster_instance_type = "t2.micro" application_cluster_launch_configuration_security_groups = ["List", "of", "SecurityGroupIDs"] + application_cluster_user_data = "your-userdata-script-as-string" #can be loaded from a file + application_cluster_instance_role_id = "RoleIDForInstanceProfile" + application_cluster_application_name = "AwesomeApplication" application_cluster_environment = "stage" - application_cluster_vpc_id = "your-vpc-id" - application_cluster_subnet_ids = ["List", "of", "SubnetIds"] application_cluster_max_size = 2 # the maximum size of the cluster application_cluster_min_size = 1 # the minimum size of the cluster - application_cluster_ssl_cert_arn = "${data.aws_acm_certificate.certificate.arn}" - application_cluster_user_data = "your-userdata-script-as-string" #can be loaded from a file - application_cluster_lb_access_log_bucket = "bucket-name-for-logging" - application_cluster_instance_role_id = "RoleIDForInstanceProfile" -} - -data "aws_acm_certificate" "certificate" { - domain = "your-awsome-domain.tld" - statuses = ["ISSUED"] + application_cluster_subnet_ids = ["List", "of", "SubnetIds"] + application_cluster_vpc_id = "your-vpc-id" + loadbalancer_listener_arn = "arn-of-loadbalancer-listener" + loadbalancer_listener_ssl_arn = "arn-of-loadbalancer-ssl-listener" + application_cluster_listener_rule_condition_field = "host-header" + application_cluster_listener_rule_condition_values = ["*.your-awsome-domain.tld"] } data "aws_ami" "appserver" { @@ -148,5 +111,4 @@ data "aws_ami" "appserver" { values = ["appserver-image"] } } - ``` diff --git a/application_cluster/auto_scaling_group.tf b/application_cluster/auto_scaling_group.tf new file mode 100644 index 0000000..b767d64 --- /dev/null +++ b/application_cluster/auto_scaling_group.tf @@ -0,0 +1,65 @@ +resource "aws_launch_configuration" "application_cluster_appserver_launch_configuration" { + image_id = "${var.application_cluster_ami_id}" + instance_type = "${var.application_cluster_instance_type}" + security_groups = ["${var.application_cluster_launch_configuration_security_groups}"] + enable_monitoring = "${var.application_cluster_launch_configuration_detailed_monitoring}" + user_data = "${var.application_cluster_user_data}" + # Instance Role has to be defined outsite of this role + iam_instance_profile = "${aws_iam_instance_profile.appserver_instance_profile.id}" + lifecycle { + create_before_destroy = true + } +} + +resource "aws_autoscaling_group" "application_cluster_appserver_auto_scaling_group" { + name = "${var.application_cluster_application_name}-${var.application_cluster_environment}-asg" + launch_configuration = "${aws_launch_configuration.application_cluster_appserver_launch_configuration.id}" + max_size = "${var.application_cluster_max_size}" + min_size = "${var.application_cluster_min_size}" + vpc_zone_identifier = ["${var.application_cluster_subnet_ids}"] + tag { + key = "Name" + value = "ASG - ${var.application_cluster_application_name} - ${var.application_cluster_environment}" + propagate_at_launch = "${var.application_cluster_propagate_at_launch}" + } +} + +resource "aws_lb_listener_rule" "application_cluster_listener_rule" { + listener_arn = "${var.loadbalancer_listener_arn}" + + action { + target_group_arn = "${aws_lb_target_group.application_cluster_target_group.arn}" + type = "forward" + } + + condition { + field = "${var.application_cluster_listener_rule_condition_field}" + values = "${var.application_cluster_listener_rule_condition_values}" + } +} + +resource "aws_lb_listener_rule" "application_cluster_listener_ssl_rule" { + listener_arn = "${var.loadbalancer_listener_ssl_arn}" + + action { + target_group_arn = "${aws_lb_target_group.application_cluster_target_group.arn}" + type = "forward" + } + + condition { + field = "${var.application_cluster_listener_rule_condition_field}" + values = "${var.application_cluster_listener_rule_condition_values}" + } +} + +resource "aws_lb_target_group" "application_cluster_target_group" { + name = "${var.application_cluster_application_name}-${var.application_cluster_environment}-target-group" + port = "${var.application_cluster_instance_port_http}" + protocol = "HTTP" + vpc_id = "${var.application_cluster_vpc_id}" +} + +resource "aws_autoscaling_attachment" "application_cluster_autoscaling_attachment" { + autoscaling_group_name = "${aws_autoscaling_group.application_cluster_appserver_auto_scaling_group.id}" + alb_target_group_arn = "${aws_lb_target_group.application_cluster_target_group.arn}" +} diff --git a/iam.tf b/application_cluster/iam.tf similarity index 100% rename from iam.tf rename to application_cluster/iam.tf diff --git a/variables.tf b/application_cluster/variables.tf similarity index 59% rename from variables.tf rename to application_cluster/variables.tf index 9b65267..61b0a81 100644 --- a/variables.tf +++ b/application_cluster/variables.tf @@ -1,37 +1,29 @@ -#Loadbalancer -variable "application_cluster_lb_security_groups" { - description = "security-groups which should be assigned to the lb" - type = "list" -} - -variable "application_cluster_lb_access_log_bucket" { - description = "the bucket name to save the lb-access-logs to. The application-data-bucket of all accounts is configured for log-file-access" +variable "application_cluster_ami_id" { + description = "the AMI with which the app-servers should be created" } -variable "application_cluster_lb_access_log_folder" { - description = "the folder where the logs should be saved. The application-data-bucket of all accounts is configured with the default path" - default = "logs/access" +variable "application_cluster_instance_type" { + description = "the size of the instances, e.g. t2.micro" } -variable "application_cluster_access_log_enabled" { - description = "enable/disable the logging of access (default: true)" - default = true +variable "application_cluster_launch_configuration_security_groups" { + description = "Security-Groups to append to the instances" + type = "list" } -variable "application_cluster_loadbalancer_type" { - description = "which lb type to use: application or network (default: application)" - default = "application" - type = "string" +variable "application_cluster_launch_configuration_detailed_monitoring" { + description = "Enable/disable detailed monitoring" + default = false } -variable "application_cluster_ssl_cert_arn" { - description = "The ssl-certificate for the lb" +variable "application_cluster_user_data" { + description = "Custom start-up script in base64-style" default = "" } -# Appserver - Cluster -variable "application_cluster_ami_id" { - description = "the AMI with which the app-servers should be created" +variable "application_cluster_instance_role_id" { + description = "the instance-role to attach to the appservers" + default = "" } variable "application_cluster_application_name" { @@ -47,33 +39,16 @@ variable "application_cluster_instance_port_http" { description = "the port for http on the instances" } -variable "application_cluster_instance_role_id" { - description = "the instance-role to attach to the appservers" - default = "" -} - -variable "application_cluster_instance_type" { - description = "the size of the instances, e.g. t2.micro" -} - variable "application_cluster_max_size" { default = 1 description = "defines the max-value of the autoscaling group" } + variable "application_cluster_min_size" { default = 1 description = "defineds the min-value for the autoscaling group" } -variable "application_cluster_propagate_at_launch" { - default = true -} - -variable "application_cluster_launch_configuration_security_groups" { - description = "Security-Groups to append to the instances" - type = "list" -} - variable "application_cluster_subnet_ids" { type = "list" } @@ -83,17 +58,26 @@ variable "application_cluster_vpc_id" { type = "string" } -variable "application_cluster_user_data" { - description = "Custom start-up script in base64-style" - default = "" +variable "application_cluster_propagate_at_launch" { + default = true } -variable "application_cluster_ssl_policy" { - description = "Policy for SSL" - default = "ELBSecurityPolicy-TLS-1-2-2017-01" +variable "loadbalancer_listener_arn" { + description = "arn of listener from loadbalancer" + type = "string" } -variable "application_cluster_launch_configuration_detailed_monitoring" { - description = "Enable/disable detailed monitoring" - default = false +variable "loadbalancer_listener_ssl_arn" { + description = "arn of ssl listener from loadbalancer" + type = "string" +} + +variable "application_cluster_listener_rule_condition_field" { + description = "field on which the condition should be triggered" + type = "string" +} + +variable "application_cluster_listener_rule_condition_values" { + description = "values which should be used on condition" + type = "list" } diff --git a/auto_scaling_group.tf b/auto_scaling_group.tf deleted file mode 100644 index a780383..0000000 --- a/auto_scaling_group.tf +++ /dev/null @@ -1,25 +0,0 @@ -resource "aws_launch_configuration" "application_cluster_appserver_launch_configuration" { - image_id = "${var.application_cluster_ami_id}" - instance_type = "${var.application_cluster_instance_type}" - security_groups = ["${var.application_cluster_launch_configuration_security_groups}"] - enable_monitoring = "${var.application_cluster_launch_configuration_detailed_monitoring}" - user_data = "${var.application_cluster_user_data}" - # Instance Role has to be defined outsite of this role - iam_instance_profile = "${aws_iam_instance_profile.appserver_instance_profile.id}" - lifecycle { - create_before_destroy = true - } -} - -resource "aws_autoscaling_group" "application_cluster_appserver_auto_scaling_group" { - name = "${var.application_cluster_application_name}-${var.application_cluster_environment}-asg" - launch_configuration = "${aws_launch_configuration.application_cluster_appserver_launch_configuration.id}" - max_size = "${var.application_cluster_max_size}" - min_size = "${var.application_cluster_min_size}" - vpc_zone_identifier = ["${var.application_cluster_subnet_ids}"] - tag { - key = "Name" - value = "ASG - ${var.application_cluster_application_name} - ${var.application_cluster_environment}" - propagate_at_launch = "${var.application_cluster_propagate_at_launch}" - } -} \ No newline at end of file diff --git a/loadbalancer.tf b/loadbalancer/loadbalancer.tf similarity index 55% rename from loadbalancer.tf rename to loadbalancer/loadbalancer.tf index 22f7c4d..02e63d7 100644 --- a/loadbalancer.tf +++ b/loadbalancer/loadbalancer.tf @@ -1,4 +1,4 @@ -resource "aws_lb" "application_cluster_loadbalancer" { +resource "aws_lb" "loadbalancer" { access_logs { bucket = "${var.application_cluster_lb_access_log_bucket}" prefix = "${var.application_cluster_lb_access_log_folder}/${var.application_cluster_environment}" @@ -17,38 +17,33 @@ resource "aws_lb" "application_cluster_loadbalancer" { } } -resource "aws_lb_target_group" "application_cluster_target_group" { - name = "${var.application_cluster_application_name}-${var.application_cluster_environment}-target-group" - port = "${var.application_cluster_instance_port_http}" - protocol = "HTTP" - vpc_id = "${var.application_cluster_vpc_id}" -} - -resource "aws_autoscaling_attachment" "application_cluster_autoscaling_attachment" { - autoscaling_group_name = "${aws_autoscaling_group.application_cluster_appserver_auto_scaling_group.id}" - alb_target_group_arn = "${aws_lb_target_group.application_cluster_target_group.arn}" -} - -resource "aws_lb_listener" "application_cluster_listener" { - load_balancer_arn = "${aws_lb.application_cluster_loadbalancer.arn}" +resource "aws_lb_listener" "loadbalancer_listener" { + load_balancer_arn = "${aws_lb.loadbalancer.arn}" port = "80" protocol = "HTTP" default_action { - target_group_arn = "${aws_lb_target_group.application_cluster_target_group.arn}" + target_group_arn = "${aws_lb_target_group.loadbalancer_default_target_group.arn}" type = "forward" } } -resource "aws_lb_listener" "application_cluster_listener_ssl" { - load_balancer_arn = "${aws_lb.application_cluster_loadbalancer.arn}" +resource "aws_lb_listener" "loadbalancer_listener_ssl" { + load_balancer_arn = "${aws_lb.loadbalancer.arn}" port = "443" protocol = "HTTPS" ssl_policy = "${var.application_cluster_ssl_policy}" certificate_arn = "${var.application_cluster_ssl_cert_arn}" default_action { - target_group_arn = "${aws_lb_target_group.application_cluster_target_group.arn}" + target_group_arn = "${aws_lb_target_group.loadbalancer_default_target_group.arn}" type = "forward" } } + +resource "aws_lb_target_group" "loadbalancer_default_target_group" { + name = "DEFAULT-${substr(var.application_cluster_application_name, 0, min(16,length(var.application_cluster_application_name)))}-${substr(var.application_cluster_environment, 0, min(4, length(var.application_cluster_environment)))}-tg" + port = "${var.application_cluster_instance_port_http}" + protocol = "HTTP" + vpc_id = "${var.application_cluster_vpc_id}" +} diff --git a/loadbalancer/output.tf b/loadbalancer/output.tf new file mode 100644 index 0000000..b2af4fc --- /dev/null +++ b/loadbalancer/output.tf @@ -0,0 +1,43 @@ +output "loadbalancer_id" { + value = "${aws_lb.loadbalancer.id}" +} + +output "loadbalancer_arn" { + value = "${aws_lb.loadbalancer.arn}" +} + +output "loadbalancer_dns_name" { + value = "${aws_lb.loadbalancer.dns_name}" +} + +output "loadbalancer_zone_id" { + value = "${aws_lb.loadbalancer.zone_id}" +} + +output "loadbalancer_listener_id" { + value = "${aws_lb_listener.loadbalancer_listener.id}" +} + +output "loadbalancer_listener_arn" { + value = "${aws_lb_listener.loadbalancer_listener.arn}" +} + +output "loadbalancer_listener_ssl_id" { + value = "${aws_lb_listener.loadbalancer_listener_ssl.id}" +} + +output "loadbalancer_listener_ssl_arn" { + value = "${aws_lb_listener.loadbalancer_listener_ssl.arn}" +} + +output "loadbalancer_default_target_group_id" { + value = "${aws_lb_target_group.loadbalancer_default_target_group.id}" +} + +output "loadbalancer_default_target_group_arn" { + value = "${aws_lb_target_group.loadbalancer_default_target_group.arn}" +} + +output "loadbalancer_default_target_group_vpc_id" { + value = "${aws_lb_target_group.loadbalancer_default_target_group.vpc_id}" +} diff --git a/loadbalancer/variables.tf b/loadbalancer/variables.tf new file mode 100644 index 0000000..0685c11 --- /dev/null +++ b/loadbalancer/variables.tf @@ -0,0 +1,56 @@ +variable "application_cluster_lb_security_groups" { + description = "security-groups which should be assigned to the lb" + type = "list" +} + +variable "application_cluster_lb_access_log_bucket" { + description = "the bucket name to save the lb-access-logs to. The application-data-bucket of all accounts is configured for log-file-access" +} + +variable "application_cluster_lb_access_log_folder" { + description = "the folder where the logs should be saved. The application-data-bucket of all accounts is configured with the default path" + default = "logs/access" +} + +variable "application_cluster_access_log_enabled" { + description = "enable/disable the logging of access (default: true)" + default = true +} + +variable "application_cluster_loadbalancer_type" { + description = "which lb type to use: application or network (default: application)" + default = "application" + type = "string" +} + +variable "application_cluster_ssl_cert_arn" { + description = "The ssl-certificate for the lb" + default = "" +} + +variable "application_cluster_application_name" { + description = "the name of the application beeing build" +} + +variable "application_cluster_environment" { + description = "the environement of the cluster, e.g. stage or live" +} + +variable "application_cluster_instance_port_http" { + default = 80 + description = "the port for http on the instances" +} + +variable "application_cluster_subnet_ids" { + type = "list" +} + +variable "application_cluster_vpc_id" { + description = "vpc to attach target groups to" + type = "string" +} + +variable "application_cluster_ssl_policy" { + description = "Policy for SSL" + default = "ELBSecurityPolicy-TLS-1-2-2017-01" +} diff --git a/output.tf b/output.tf deleted file mode 100644 index 564868e..0000000 --- a/output.tf +++ /dev/null @@ -1,11 +0,0 @@ -output "application_cluster_loadbalancer_id" { - value = "${aws_lb.application_cluster_loadbalancer.id}" -} - -output "application_cluster_loadbalancer_dns" { - value = "${aws_lb.application_cluster_loadbalancer.dns_name}" -} - -output "application_cluster_loadbalancer_zone_id" { - value = "${aws_lb.application_cluster_loadbalancer.zone_id}" -}