{"id":942,"date":"2023-11-27T15:58:36","date_gmt":"2023-11-27T15:58:36","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=942"},"modified":"2023-11-27T15:58:36","modified_gmt":"2023-11-27T15:58:36","slug":"deploy-java-applications-aws-autoscaling","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=942","title":{"rendered":"How to Deploy Java Applications on AWS ASG Using Terraform"},"content":{"rendered":"<p>In this <a href=\"https:\/\/devopscube.com\/devops-projects\/\">DevOps Project<\/a>, you will learn about how to set up a scalable Java application with ASG, ALB, and RDS using Terraform<\/p>\n<h2 id=\"tools-services-used\">Tools &amp; Services Used<\/h2>\n<p>For this setup, I have used the following DevOps Tools<\/p>\n<ol>\n<li><strong>GitHub<\/strong>: Repository to store IaC<\/li>\n<li><strong>Packer<\/strong>: To build Java application <a href=\"https:\/\/devopscube.com\/packer-tutorial-for-beginners\/\">AMIs<\/a><\/li>\n<li><strong>Ansible<\/strong>: To configure java application during the AMI building process<\/li>\n<li><strong>Terraform<\/strong>: To provision AWS resources<\/li>\n<li><strong>Python Boto3<\/strong>: To retrieve RDS credentials from AWS secrets manager.<\/li>\n<\/ol>\n<p>Following are the AWS services used.<\/p>\n<ol>\n<li><strong>IAM<\/strong>: To create IAM Role\/Instance Profile for Java Application Instance.<\/li>\n<li><strong>RDS<\/strong>: For application database<\/li>\n<li><strong>AWS Secrets Manager<\/strong>: To store RDS credential during RDS launch.<\/li>\n<li><strong>AWS Parameter Store<\/strong>: To get the RDS endpoint.<\/li>\n<li><strong>Autoscaling Group<\/strong>: To deploy the Java application.<\/li>\n<li><strong>Application Load Balancer<\/strong>: To have a static DNS endpoint for the java application running in the autoscaling group.<\/li>\n<\/ol>\n<h2 id=\"setup-architecture\">Setup Architecture<\/h2>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-151-4.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"1381\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-151-4.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/image-151-4.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/image-151-4.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-151-4.png 2183w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h2 id=\"setup-prerequisites\">Setup Prerequisites<\/h2>\n<p>Before starting the setup, you will need the following tools and utilities installed and configured on your workstation.<\/p>\n<ol>\n<li>Packer<\/li>\n<li>Ansible<\/li>\n<li>Terraform<\/li>\n<li>JDK-17<\/li>\n<li>Maven-v3.9.4<\/li>\n<li><a href=\"https:\/\/devopscube.com\/install-configure-aws-cli-linux\/\">AWS CLI<\/a>, configured with default region as us-west-2 and AWS credentials that have admin access to the AWS account.<\/li>\n<\/ol>\n<p>We will be using the default VPC in the us-west-2 (Oregon) region. There will be four default subnets. We will be using three subnets from the following three availability zones:<\/p>\n<ol>\n<li>us-west-2a<\/li>\n<li>us-west-2b<\/li>\n<li>us-west-2c<\/li>\n<\/ol>\n<p>Ensure you have an <strong>existing key pair in your AWS account for the Oregon region<\/strong>. We will use it with instances to enable SSH access.<\/p>\n<h2 id=\"build-java-application\">Build Java Application<\/h2>\n<p>Clone this repository to your local system to build a Java Application.<\/p>\n<pre><code>git clone github.com\/pet-clinic-project\/pet-clinic-app.git<\/code><\/pre>\n<p>CD into <code>pet-clinic-app<\/code> folder and run the below command to build the application.<\/p>\n<pre><code>mvn clean install<\/code><\/pre>\n<p>After the build process finishes you can see a new folder named <code>target<\/code>, CD into the target folder you can find the JAR file for the application as given below<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-115-4.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"426\" height=\"322\"><\/figure>\n<h2 id=\"provision-aws-services\">Provision AWS Services<\/h2>\n<p>Clone this repository to your local system and the code for this project is in the <a href=\"https:\/\/github.com\/techiescamp\/devops-projects\/tree\/main\/03-scalable-java-app?ref=devopscube.com\">03-scalable-java-app<\/a> folder.<\/p>\n<pre><code>https:\/\/github.com\/techiescamp\/devops-projects.git<\/code><\/pre>\n<p>The folders and files inside the project folder are listed below.<\/p>\n<pre><code>.\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 ansible\n\u2502   \u251c\u2500\u2500 files\n\u2502   \u2502   \u251c\u2500\u2500 application.properties\n\u2502   \u2502   \u251c\u2500\u2500 properties.py\n\u2502   \u2502   \u2514\u2500\u2500 start.sh\n\u2502   \u251c\u2500\u2500 java-app.pkr.hcl\n\u2502   \u251c\u2500\u2500 java-app.yml\n\u2502   \u251c\u2500\u2500 roles\n\u2502   \u2502   \u2514\u2500\u2500 java\n\u2502   \u2502       \u2514\u2500\u2500 tasks\n\u2502   \u2502           \u251c\u2500\u2500 app.yml\n\u2502   \u2502           \u251c\u2500\u2500 backends.yml\n\u2502   \u2502           \u251c\u2500\u2500 cloudwatch.yml\n\u2502   \u2502           \u251c\u2500\u2500 java.yml\n\u2502   \u2502           \u251c\u2500\u2500 main.yml\n\u2502   \u2502           \u2514\u2500\u2500 python.yml\n\u2502   \u2514\u2500\u2500 templates\n\u2502       \u251c\u2500\u2500 config.json.j2\n\u2502       \u2514\u2500\u2500 index.html.j2\n\u2514\u2500\u2500 terraform\n    \u251c\u2500\u2500 alb-asg\n    \u2502   \u251c\u2500\u2500 main.tf\n    \u2502   \u251c\u2500\u2500 terraform.tfstate\n    \u2502   \u251c\u2500\u2500 terraform.tfstate.backup\n    \u2502   \u2514\u2500\u2500 variable.tf\n    \u251c\u2500\u2500 modules\n    \u2502   \u251c\u2500\u2500 alb-asg\n    \u2502   \u2502   \u251c\u2500\u2500 alb.tf\n    \u2502   \u2502   \u251c\u2500\u2500 asg.tf\n    \u2502   \u2502   \u251c\u2500\u2500 iam-policy.tf\n    \u2502   \u2502   \u2514\u2500\u2500 variable.tf\n    \u2502   \u2514\u2500\u2500 rds\n    \u2502       \u251c\u2500\u2500 main.tf\n    \u2502       \u251c\u2500\u2500 outputs.tf\n    \u2502       \u2514\u2500\u2500 variables.tf\n    \u251c\u2500\u2500 rds\n    \u2502   \u251c\u2500\u2500 main.tf\n    \u2502   \u251c\u2500\u2500 terraform.tfstate\n    \u2502   \u251c\u2500\u2500 terraform.tfstate.backup\n    \u2502   \u2514\u2500\u2500 variables.tf\n    \u2514\u2500\u2500 vars\n        \u251c\u2500\u2500 alb-asg.tfvars\n        \u2514\u2500\u2500 rds.tfvars<\/code><\/pre>\n<h2 id=\"provision-java-application-ami\">Provision Java Application AMI<\/h2>\n<p>The first step is to provision an AMI for your Java Application. CD into the ansible folder and follow the below steps before creating the AMI.<\/p>\n<p><strong>STEP 1:<\/strong> Copy your JAR file inside the <strong><code>ansible\/files<\/code><\/strong> folder and specify the name of your JAR file in the <strong><code>ansible\/java-app.yml<\/code><\/strong> file as shown below.<\/p>\n<pre><code>---\n- name: Install Java\n  hosts: all\n  become: yes\n  remote_user: ubuntu\n\n  vars:\n    source_dir: files\n    dest_dir: \/home\/ubuntu\/\n    files:\n      - properties.py\n      - start.sh\n      - pet-clinic-1.0.1.jar\n\n  roles:\n    - java<\/code><\/pre>\n<p><strong><code>pet-clinic-1.0.1.jar<\/code><\/strong> is the name of my JAR file, you make sure to replace with the name of your Jar file.<\/p>\n<p><strong>STEP 2:<\/strong> Modify the Python script <strong><code>ansible\/files\/properties.py<\/code><\/strong><\/p>\n<pre><code>import boto3\nimport json\n\nregion = 'us-west-2'\nparameter_store = '\/dev\/petclinic\/rds_endpoint'\nsecret_name_tag = 'dev-rds-db'\nfile_path = \"\/opt\/application.properties\"\n\nssm = boto3.client('ssm', region_name=region)\n\nrds_endpoint = ssm.get_parameter(Name=parameter_store)['Parameter']['Value']\n\nsecrets_client = boto3.client('secretsmanager', region_name=region)\n\nsecrets_list = secrets_client.list_secrets()\nsecret_arn = None\nfor secret in secrets_list['SecretList']:\n    if 'Tags' in secret:\n        for tag in secret['Tags']:\n            if tag['Key'] == 'Name' and tag['Value'] == secret_name_tag:\n                secret_arn = secret['ARN']\n                break\n\nif secret_arn is None:\n    print(f\"Secret with name tag '{secret_name_tag}' not found.\")\n    exit(1)\n\nresponse = secrets_client.get_secret_value(SecretId=secret_arn)\nsecret_value = response['SecretString']\n\nsecret_data = json.loads(secret_value)\n\nwith open(file_path, 'r') as f:\n    file_contents = f.read()\n\nfile_contents = file_contents.replace(\"spring.datasource.url=jdbc:mysql:\/\/localhost:3306\/petclinic\", f\"spring.datasource.url=jdbc:mysql:\/\/{rds_endpoint}\")\nfile_contents = file_contents.replace(\"spring.datasource.username=petclinic\", f\"spring.datasource.username={secret_data['username']}\")\nfile_contents = file_contents.replace(\"spring.datasource.password=petclinic\", f\"spring.datasource.password={secret_data['password']}\")\n\n\nwith open(file_path, 'w') as f:\n        f.write(file_contents)<\/code><\/pre>\n<p>This Python script retrieves your RDS username and password from the secret manager and RDS endpoint from the parameter store.<\/p>\n<p>First it creates an ssm client and retrieves the RDS endpoint from the Parameter Store. Then it creates a secret manager client and lists the secrets in the secrets manager, then uses the name tag to identify the secret which contains the username and password from the RDS database.<\/p>\n<p>It updates the <strong><code>ansible\/files\/application.properties<\/code><\/strong> configuration file with the username, password, and endpoint, so that your application can connect to the RDS database.<\/p>\n<p><strong>STEP 3:<\/strong> Update your JAR file name inside the startup script <strong><code>ansible\/files\/start.sh<\/code><\/strong><\/p>\n<pre><code>#!\/bin\/bash\n\nJAR_FILE=\/home\/ubuntu\/pet-clinic-1.0.1.jar\nAPP_PROPERTIES=\/opt\/application.properties\nPROPERTIES_SCRIPT=\/home\/ubuntu\/properties.py\n\nsudo python3 ${PROPERTIES_SCRIPT}\n\nsudo java -jar \"${JAR_FILE}\" --spring.config.location=\"${APP_PROPERTIES}\" --spring.profiles.active=mysql &amp;<\/code><\/pre>\n<p>By running this script it will run the <strong><code>ansible\/files\/properties.py<\/code><\/strong> and then run the Java application and connect it with the RDS database.<\/p>\n<p>Replace <strong><code>pet-clinic-1.0.1.jar<\/code><\/strong> with your JAR file name.<\/p>\n<p><strong>STEP 4:<\/strong> Update the Packer template  <strong><code>ansible\/java-app.pkr.hcl<\/code><\/strong><\/p>\n<pre><code>variable \"ami_id\" {\n  type    = string\n  default = \"ami-03f65b8614a860c29\"\n}\n\nlocals {\n    app_name = \"java-app-1.0.1\"\n}\n\nsource \"amazon-ebs\" \"java-app\" {\n  ami_name      = \"PACKER-${local.app_name}\"\n  instance_type = \"t2.medium\"\n  region        = \"us-west-2\"\n  source_ami    = \"${var.ami_id}\"\n  ssh_username  = \"ubuntu\"\n  tags = {\n    Env  = \"DEMO\"\n    Name = \"PACKER-${local.app_name}\"\n  }\n}\n\nbuild {\n  sources = [\"source.amazon-ebs.java-app\"]\n\n  provisioner \"ansible\" {\n    playbook_file = \"java-app.yml\"\n  }\n\n}\n<\/code><\/pre>\n<p>In this template update the ami_id, app_name, and instance_type you are going to use.<\/p>\n<p><strong>STEP 5:<\/strong> Now, validate your packer template using the command<\/p>\n<pre><code>packer validate java-app.pkr.hcl<\/code><\/pre>\n<p><strong>STEP 6:<\/strong> If the packer template is valid build your AMI using the command<\/p>\n<pre><code>packer build java-app.pkr.hcl<\/code><\/pre>\n<p>Once your AMI is provisioned move on to the next process.<\/p>\n<h2 id=\"rds-provisioning\">RDS Provisioning<\/h2>\n<p>After provisioning the AMI, start provisioning the RDS database for the application. CD into the terraform folder and follow the steps.<\/p>\n<p><strong>Step 1:<\/strong> Modify <strong><code>terraform\/vars\/rds.tfvars<\/code><\/strong> file<\/p>\n<p>CD into the <strong><code>terraform\/vars<\/code><\/strong> folder and update the <strong><code>rds.tfvars<\/code><\/strong> file with vpc, subnets, and other configurations.<\/p>\n<pre><code># Network Vars\nregion              = \"us-west-2\"\nvpc_id              = \"vpc-0a5ca4a92c2e10163\"\nsubnet_ids          = [\"subnet-058a7514ba8adbb07\", \"subnet-032f5077729435858\", \"subnet-0dbcd1ac168414927\"]\nmulti_az            = false\npublicly_accessible = true\n\n# DB Vars\ndb_engine                   = \"mysql\"\ndb_storage_type             = \"gp2\"\ndb_username                 = \"techiescamp\"\ndb_instance_class           = \"db.t2.micro\"\ndb_storage_size             = 20\nset_secret_manager_password = true\nset_db_password             = false\ndb_password                 = \"rdssecret\"\n\n# Security Group Vars\ningress_from_port   = 3306\ningress_to_port     = 3306\ningress_protocol    = \"tcp\"\ningress_cidr_blocks = [\"0.0.0.0\/0\"]\n\negress_from_port   = 0\negress_to_port     = 0\negress_protocol    = \"-1\"\negress_cidr_blocks = [\"0.0.0.0\/0\"]\n\n# Backup vars\nbackup_retention_period  = 7\ndelete_automated_backups = true\ncopy_tags_to_snapshot    = true\nskip_final_snapshot      = true\napply_immediately        = true\n\n# Parameter store\nparameter_store_secret_name = \"\/dev\/petclinic\/rds_endpoint\"\ntype                        = \"String\"\n\n# Tag Vars\nowner       = \"techiescamp\"\nenvironment = \"dev\"\ncost_center = \"techiescamp-commerce\"\napplication = \"rds\"<\/code><\/pre>\n<p><strong>STEP 2:<\/strong> After modifying <strong><code>terraform\/vars\/rds.tfvars<\/code><\/strong> with your configurations, initialize Terraform inside the <strong><code>terraform\/rds<\/code><\/strong> folder.<\/p>\n<pre><code>terraform init<\/code><\/pre>\n<p><strong>STEP 3:<\/strong> Before start provisioning RDS make sure you have given the right configurations using the plan command.<\/p>\n<pre><code>terraform plan -var-file=..\/vars\/rds.tfvars<\/code><\/pre>\n<p><strong>STEP 4:<\/strong> Start provisioning RDS<\/p>\n<pre><code>terraform apply -var-file=..\/vars\/rds.tfvars<\/code><\/pre>\n<p>After the code runs successfully, validate that the RDS database has provisioned and active. Also check if the RDS endpoint is stored in the Parameter Store.<\/p>\n<p>RDS username and password will be stored in the Secret Manager with a long random name as shown below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-116-5.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"944\" height=\"304\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-116-5.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-116-5.png 944w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h2 id=\"alb-and-asg-provisioning\">ALB and ASG Provisioning<\/h2>\n<p>After provisioning the RDS database, start provisioning the ALB and ASG by following the steps below.<\/p>\n<p><strong>Step 1:<\/strong> Modify <strong><code>terraform\/vars\/alb-asg.tfvars<\/code><\/strong> file<\/p>\n<p>CD into the <strong><code>terraform\/vars\/<\/code><\/strong> folder and update the <strong><code>alb-asg.tfvars<\/code><\/strong> fil with vpc, subnets, ami-id, key, and other configurations with your configuration.<\/p>\n<pre><code>#Network\nregion  = \"us-west-2\"\nvpc_id  = \"vpc-0a5ca4a92c2e10163\"\nsubnets = [\"subnet-058a7514ba8adbb07\", \"subnet-032f5077729435858\", \"subnet-0dbcd1ac168414927\"]\n\n#alb_sg\ningress_alb_from_port   = 80\ningress_alb_to_port     = 80\ningress_alb_protocol    = \"tcp\"\ningress_alb_cidr_blocks = [\"0.0.0.0\/0\"]\negress_alb_from_port    = 0\negress_alb_to_port      = 0\negress_alb_protocol     = \"-1\"\negress_alb_cidr_blocks  = [\"0.0.0.0\/0\"]\n\n#alb\ninternal          = false\nloadbalancer_type = \"application\"\n\n#target_group\ntarget_group_port                = 8080\ntarget_group_protocol            = \"HTTP\"\ntarget_type                      = \"instance\"\nload_balancing_algorithm         = \"round_robin\"\nhealth_check_path                = \"\/\"\nhealth_check_port                = 8080\nhealth_check_protocol            = \"HTTP\"\nhealth_check_interval            = 30\nhealth_check_timeout             = 5\nhealth_check_healthy_threshold   = 2\nhealth_check_unhealthy_threshold = 2\n\n#instance_sg\ningress_asg_cidr_from_port = 22\ningress_asg_cidr_to_port   = 22\ningress_asg_cidr_protocol  = \"tcp\"\ningress_asg_cidr_blocks    = [\"0.0.0.0\/0\"]\ningress_asg_sg_from_port   = 8080\ningress_asg_sg_to_port     = 8080\ningress_asg_sg_protocol    = \"tcp\"\negress_asg_from_port       = 0\negress_asg_to_port         = 0\negress_asg_protocol        = \"-1\"\negress_asg_cidr_blocks     = [\"0.0.0.0\/0\"]\n\n#asg\nmax_size         = 3\nmin_size         = 1\ndesired_capacity = 2\n\n#listener\nlistener_port     = 80\nlistener_protocol = \"HTTP\"\nlistener_type     = \"forward\"\n\n#launch_template\nami_id               = \"ami-0f7a74cccd5a223bc\"\ninstance_type        = \"t2.medium\"\nkey_name             = \"techiescamp\"\nuser_data            = &lt;&lt;-EOF\n#!\/bin\/bash\nbash \/home\/ubuntu\/start.sh\nEOF\npublic_access        = true\ninstance_warmup_time = 30\ntarget_value         = 50\n\nowner       = \"techiescamp\"\nenvironment = \"dev\"\ncost_center = \"techiescamp-commerce\"\napplication = \"pet-clinic\"<\/code><\/pre>\n<p>Each instance will have an IAM role attached to it while provisioning. I attached an IAM role with admin permissions, you can modify the IAM role in the <strong><code>\/terraform\/modules\/alb-asg\/iam-policy.tf<\/code><\/strong> file with the permissions you require.<\/p>\n<p><strong>STEP 2:<\/strong> After modifying <code><strong>alb-asg.tfvar<\/strong>s<\/code> with your configurations, initialize Terraform inside the <strong><code>terraform\/alb-asg<\/code><\/strong> folder.<\/p>\n<pre><code>terraform init<\/code><\/pre>\n<p><strong>STEP 3:<\/strong> Before start provisioning ALB and ASG make sure you have given the right configurations using the plan command.<\/p>\n<pre><code>terraform plan -var-file=..\/vars\/alb-asg.tfvars<\/code><\/pre>\n<p><strong>STEP 4:<\/strong> Start provisioning ALB and ASG<\/p>\n<pre><code>terraform apply -var-file=..\/vars\/alb-asg.tfvars<\/code><\/pre>\n<p>After the code runs successfully, validate ALB and ASG has provisioned. And you can check the health of your instance in the target group.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/2-8.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1874\" height=\"982\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/2-8.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/2-8.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/2-8.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/2-8.png 1874w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>If your instances are healthy try to access your application in the browser using the load-balancer DNS as shown below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/3-5.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1750\" height=\"962\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/3-5.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/3-5.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/3-5.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/3-5.png 1750w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>Make sure your instances are connected to the RDS database.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/2023-11-08_19-03-11-1.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1736\" height=\"438\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/2023-11-08_19-03-11-1.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/2023-11-08_19-03-11-1.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/2023-11-08_19-03-11-1.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/2023-11-08_19-03-11-1.png 1736w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/deploy-java-applications-aws-autoscaling\/\" target=\"_blank\" rel=\"noopener noreferrer\">How to Deploy Java Applications on AWS ASG Using Terraform \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/deploy-java-applications-aws-autoscaling\/<\/p>\n","protected":false},"author":1,"featured_media":943,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-942","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=942"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/942\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/943"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=942"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=942"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}