diff options
Diffstat (limited to 'fdio.infra.terraform/1n_aws_t3/main.tf')
-rw-r--r-- | fdio.infra.terraform/1n_aws_t3/main.tf | 613 |
1 files changed, 613 insertions, 0 deletions
diff --git a/fdio.infra.terraform/1n_aws_t3/main.tf b/fdio.infra.terraform/1n_aws_t3/main.tf new file mode 100644 index 0000000000..eb0c046b2e --- /dev/null +++ b/fdio.infra.terraform/1n_aws_t3/main.tf @@ -0,0 +1,613 @@ +locals { + bucket = "${var.application_name}-bucket" + tags = { + "Name" = "${var.application_name}" + "Environment" = "${var.application_name}" + } +} + +# Create elastic beanstalk VPC +resource "aws_vpc" "vpc" { + assign_generated_ipv6_cidr_block = true + cidr_block = var.vpc_cidr_block + enable_dns_hostnames = var.vpc_enable_dns_hostnames + enable_dns_support = var.vpc_enable_dns_support + instance_tenancy = var.vpc_instance_tenancy + tags = local.tags +} + +# Create elastic beanstalk Subnets +resource "aws_subnet" "subnet" { + depends_on = [ + aws_vpc.vpc + ] + availability_zone = var.subnet_availability_zone + assign_ipv6_address_on_creation = true + cidr_block = aws_vpc.vpc.cidr_block + ipv6_cidr_block = cidrsubnet(aws_vpc.vpc.ipv6_cidr_block, 8, 1) + map_public_ip_on_launch = true + vpc_id = aws_vpc.vpc.id + tags = local.tags +} + +resource "aws_internet_gateway" "internet_gateway" { + depends_on = [ + aws_vpc.vpc + ] + vpc_id = aws_vpc.vpc.id + tags = local.tags +} + +resource "aws_route" "route" { + depends_on = [ + aws_vpc.vpc, + aws_internet_gateway.internet_gateway + ] + destination_cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.internet_gateway.id + route_table_id = aws_vpc.vpc.main_route_table_id +} + +# Create elastic beanstalk IAM mapping +data "aws_iam_policy_document" "service" { + statement { + actions = [ + "sts:AssumeRole" + ] + principals { + type = "Service" + identifiers = ["elasticbeanstalk.amazonaws.com"] + } + effect = "Allow" + } +} + +resource "aws_iam_role" "service" { + assume_role_policy = data.aws_iam_policy_document.service.json + name = "${var.application_name}-eb-service" +} + +resource "aws_iam_role_policy_attachment" "enhanced_health" { + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkEnhancedHealth" + role = aws_iam_role.service.name +} + +resource "aws_iam_role_policy_attachment" "service" { + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkService" + role = aws_iam_role.service.name +} + +data "aws_iam_policy_document" "ec2" { + statement { + actions = [ + "sts:AssumeRole" + ] + principals { + type = "Service" + identifiers = ["ec2.amazonaws.com"] + } + effect = "Allow" + } + statement { + actions = [ + "sts:AssumeRole", + ] + principals { + type = "Service" + identifiers = ["ssm.amazonaws.com"] + } + effect = "Allow" + } +} + +resource "aws_iam_role" "ec2" { + assume_role_policy = data.aws_iam_policy_document.ec2.json + name = "${var.application_name}-eb-ec2" +} + +resource "aws_iam_instance_profile" "ec2_iam_instance_profile" { + name = "${var.application_name}-iam-instance-profile" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "multicontainer_docker" { + policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkMulticontainerDocker" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "web_tier" { + policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "worker_tier" { + policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkWorkerTier" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "ssm_automation" { + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "ssm_ec2" { + policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" + role = aws_iam_role.ec2.name +} + +resource "aws_iam_role_policy_attachment" "ecr_readonly" { + policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" + role = aws_iam_role.ec2.name +} + +resource "aws_ssm_activation" "ec2" { + depends_on = [ + aws_iam_role.ec2, + aws_iam_role_policy_attachment.ssm_ec2 + ] + name = "${var.application_name}-ec2-activation" + iam_role = aws_iam_role.ec2.id + registration_limit = 3 +} + +data "aws_iam_policy_document" "default" { + statement { + actions = [ + "elasticloadbalancing:DescribeInstanceHealth", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeTargetHealth", + "ec2:DescribeInstances", + "ec2:DescribeInstanceStatus", + "ec2:GetConsoleOutput", + "ec2:AssociateAddress", + "ec2:DescribeAddresses", + "ec2:DescribeSecurityGroups", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeScalingActivities", + "autoscaling:DescribeNotificationConfigurations", + ] + resources = ["*"] + effect = "Allow" + } + + statement { + sid = "AllowOperations" + actions = [ + "autoscaling:AttachInstances", + "autoscaling:CreateAutoScalingGroup", + "autoscaling:CreateLaunchConfiguration", + "autoscaling:DeleteLaunchConfiguration", + "autoscaling:DeleteAutoScalingGroup", + "autoscaling:DeleteScheduledAction", + "autoscaling:DescribeAccountLimits", + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeLaunchConfigurations", + "autoscaling:DescribeLoadBalancers", + "autoscaling:DescribeNotificationConfigurations", + "autoscaling:DescribeScalingActivities", + "autoscaling:DescribeScheduledActions", + "autoscaling:DetachInstances", + "autoscaling:PutScheduledUpdateGroupAction", + "autoscaling:ResumeProcesses", + "autoscaling:SetDesiredCapacity", + "autoscaling:SetInstanceProtection", + "autoscaling:SuspendProcesses", + "autoscaling:TerminateInstanceInAutoScalingGroup", + "autoscaling:UpdateAutoScalingGroup", + "cloudwatch:PutMetricAlarm", + "ec2:AssociateAddress", + "ec2:AllocateAddress", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:AuthorizeSecurityGroupIngress", + "ec2:CreateSecurityGroup", + "ec2:DeleteSecurityGroup", + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeImages", + "ec2:DescribeInstances", + "ec2:DescribeKeyPairs", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSnapshots", + "ec2:DescribeSubnets", + "ec2:DescribeVpcs", + "ec2:DisassociateAddress", + "ec2:ReleaseAddress", + "ec2:RevokeSecurityGroupEgress", + "ec2:RevokeSecurityGroupIngress", + "ec2:TerminateInstances", + "ecs:CreateCluster", + "ecs:DeleteCluster", + "ecs:DescribeClusters", + "ecs:RegisterTaskDefinition", + "elasticbeanstalk:*", + "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer", + "elasticloadbalancing:ConfigureHealthCheck", + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", + "elasticloadbalancing:DescribeInstanceHealth", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:RegisterInstancesWithLoadBalancer", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:DeregisterTargets", + "iam:ListRoles", + "iam:PassRole", + "logs:CreateLogGroup", + "logs:PutRetentionPolicy", + "rds:DescribeDBEngineVersions", + "rds:DescribeDBInstances", + "rds:DescribeOrderableDBInstanceOptions", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:ListBucket", + "sns:CreateTopic", + "sns:GetTopicAttributes", + "sns:ListSubscriptionsByTopic", + "sns:Subscribe", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + "codebuild:CreateProject", + "codebuild:DeleteProject", + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + ] + resources = ["*"] + effect = "Allow" + } + + statement { + sid = "AllowS3OperationsOnElasticBeanstalkBuckets" + actions = [ + "s3:*" + ] + resources = [ + "arn:aws:s3:::*" + ] + effect = "Allow" + } + + statement { + sid = "AllowDeleteCloudwatchLogGroups" + actions = [ + "logs:DeleteLogGroup" + ] + resources = [ + "arn:aws:logs:*:*:log-group:/aws/elasticbeanstalk*" + ] + effect = "Allow" + } + + statement { + sid = "AllowCloudformationOperationsOnElasticBeanstalkStacks" + actions = [ + "cloudformation:*" + ] + resources = [ + "arn:aws:cloudformation:*:*:stack/awseb-*", + "arn:aws:cloudformation:*:*:stack/eb-*" + ] + effect = "Allow" + } +} + +resource "aws_iam_role_policy" "default" { + depends_on = [ + aws_iam_role.ec2 + ] + name = "${var.application_name}-eb-default" + policy = data.aws_iam_policy_document.default.json + role = aws_iam_role.ec2.id +} + +# Create elastic beanstalk Application +resource "aws_s3_bucket" "bucket" { + bucket = local.bucket + tags = local.tags +} + +resource "aws_s3_object" "object" { + bucket = aws_s3_bucket.bucket.id + key = "beanstalk/app.zip" + source = "app.zip" + tags = local.tags +} + +resource "aws_elastic_beanstalk_application_version" "application_version" { + depends_on = [ + aws_elastic_beanstalk_application.application + ] + name = "${var.application_name}-base" + application = var.application_name + description = var.application_description + bucket = aws_s3_bucket.bucket.id + key = aws_s3_object.object.id + tags = local.tags +} + +resource "aws_elastic_beanstalk_application" "application" { + depends_on = [ + aws_vpc.vpc, + aws_subnet.subnet, + aws_ssm_activation.ec2 + ] + name = var.application_name + description = var.application_description + + dynamic "appversion_lifecycle" { + for_each = var.appversion_lifecycle_service_role_arn != "" ? ["true"] : [] + content { + service_role = var.appversion_lifecycle_service_role_arn + max_count = var.appversion_lifecycle_max_count + delete_source_from_s3 = var.appversion_lifecycle_delete_source_from_s3 + } + } + tags = local.tags +} + +# Create elastic beanstalk Environment +resource "aws_elastic_beanstalk_environment" "environment" { + depends_on = [ + aws_vpc.vpc, + aws_subnet.subnet, + aws_ssm_activation.ec2 + ] + application = aws_elastic_beanstalk_application.application.name + description = var.environment_description + name = var.environment_name + solution_stack_name = var.environment_solution_stack_name + tier = var.environment_tier + wait_for_ready_timeout = var.environment_wait_for_ready_timeout + version_label = var.environment_version_label + tags = local.tags + + # aws:ec2:instances + setting { + namespace = "aws:ec2:instances" + name = "InstanceTypes" + value = var.instances_instance_types + } + + # aws:ec2:vpc + setting { + namespace = "aws:ec2:vpc" + name = "VPCId" + value = aws_vpc.vpc.id + } + + setting { + namespace = "aws:ec2:vpc" + name = "Subnets" + value = aws_subnet.subnet.id + } + + setting { + namespace = "aws:ec2:vpc" + name = "ELBSubnets" + value = aws_subnet.subnet.id + } + + setting { + namespace = "aws:ec2:vpc" + name = "ELBScheme" + value = var.environment_type == "LoadBalanced" ? var.elb_scheme : "" + } + + setting { + namespace = "aws:ec2:vpc" + name = "AssociatePublicIpAddress" + value = var.associate_public_ip_address + } + + setting { + namespace = "aws:elasticbeanstalk:application" + name = "Application Healthcheck URL" + value = "/" + } + + # aws:elbv2:listener:default + setting { + namespace = "aws:elbv2:listener:default" + name = "ListenerEnabled" + value = var.default_listener_enabled + } + + # aws:elasticbeanstalk:environment + setting { + namespace = "aws:elasticbeanstalk:environment" + name = "LoadBalancerType" + value = var.environment_loadbalancer_type + } + + setting { + namespace = "aws:elasticbeanstalk:environment" + name = "ServiceRole" + value = aws_iam_role.service.name + } + + # aws:elasticbeanstalk:environment:process:default + setting { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "HealthCheckInterval" + value = var.environment_process_default_healthcheck_interval + } + + setting { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "HealthyThresholdCount" + value = var.environment_process_default_healthy_threshold_count + } + + setting { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "Port" + value = var.environment_process_default_port + } + + setting { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "Protocol" + value = var.environment_loadbalancer_type == "network" ? "TCP" : "HTTP" + } + + setting { + namespace = "aws:elasticbeanstalk:environment:process:default" + name = "UnhealthyThresholdCount" + value = var.environment_process_default_unhealthy_threshold_count + } + + # aws:autoscaling:launchconfiguration + setting { + namespace = "aws:autoscaling:launchconfiguration" + name = "IamInstanceProfile" + value = aws_iam_instance_profile.ec2_iam_instance_profile.name + } + + # aws:elasticbeanstalk:healthreporting:system + setting { + namespace = "aws:elasticbeanstalk:healthreporting:system" + name = "SystemType" + value = var.healthreporting_system_type + } + + # aws:elasticbeanstalk:managedactions + setting { + namespace = "aws:elasticbeanstalk:managedactions" + name = "ManagedActionsEnabled" + value = var.managedactions_managed_actions_enabled ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:managedactions" + name = "PreferredStartTime" + value = var.managedactions_preferred_start_time + } + + # aws:elasticbeanstalk:managedactions:platformupdate + setting { + namespace = "aws:elasticbeanstalk:managedactions:platformupdate" + name = "UpdateLevel" + value = var.managedactions_platformupdate_update_level + } + + setting { + namespace = "aws:elasticbeanstalk:managedactions:platformupdate" + name = "InstanceRefreshEnabled" + value = var.managedactions_platformupdate_instance_refresh_enabled + } + + # aws:autoscaling:asg + setting { + namespace = "aws:autoscaling:asg" + name = "MinSize" + value = var.autoscaling_asg_minsize + } + setting { + namespace = "aws:autoscaling:asg" + name = "MaxSize" + value = var.autoscaling_asg_maxsize + } + + # aws:autoscaling:trigger + setting { + namespace = "aws:autoscaling:trigger" + name = "MeasureName" + value = var.autoscaling_trigger_measure_name + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "Statistic" + value = var.autoscaling_trigger_statistic + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "Unit" + value = var.autoscaling_trigger_unit + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "LowerThreshold" + value = var.autoscaling_trigger_lower_threshold + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "LowerBreachScaleIncrement" + value = var.autoscaling_trigger_lower_breach_scale_increment + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "UpperThreshold" + value = var.autoscaling_trigger_upper_threshold + } + + setting { + namespace = "aws:autoscaling:trigger" + name = "UpperBreachScaleIncrement" + value = var.autoscaling_trigger_upper_breach_scale_increment + } + + # aws:elasticbeanstalk:hostmanager + setting { + namespace = "aws:elasticbeanstalk:hostmanager" + name = "LogPublicationControl" + value = var.hostmanager_log_publication_control ? "true" : "false" + } + + # aws:elasticbeanstalk:cloudwatch:logs + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs" + name = "StreamLogs" + value = var.cloudwatch_logs_stream_logs ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs" + name = "DeleteOnTerminate" + value = var.cloudwatch_logs_delete_on_terminate ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs" + name = "RetentionInDays" + value = var.cloudwatch_logs_retention_in_days + } + + # aws:elasticbeanstalk:cloudwatch:logs:health + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs:health" + name = "HealthStreamingEnabled" + value = var.cloudwatch_logs_health_health_streaming_enabled ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs:health" + name = "DeleteOnTerminate" + value = var.cloudwatch_logs_health_delete_on_terminate ? "true" : "false" + } + + setting { + namespace = "aws:elasticbeanstalk:cloudwatch:logs:health" + name = "RetentionInDays" + value = var.cloudwatch_logs_health_retention_in_days + } + + # aws:elasticbeanstalk:application:environment + dynamic "setting" { + for_each = var.environment_variables + content { + namespace = "aws:elasticbeanstalk:application:environment" + name = setting.key + value = setting.value + } + } +} |