├── .gitignore ├── LICENSE ├── ReadMe.md ├── cloud_watch.tf ├── cloudwatch_config └── linux_config.json.tftpl ├── data.tf ├── ec2.tf ├── iamrole.tf ├── kms.tf ├── provider.tf ├── security_group.tf ├── ssm_parameter.tf ├── user_data └── user_data.tpl ├── variable.tf └── vpc.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | backend.tf 8 | # Crash log files 9 | crash.log 10 | 11 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 12 | # .tfvars files are managed as part of configuration and so should be included in 13 | # version control. 14 | # 15 | *.tfvars 16 | *.hcl 17 | # Ignore override files as they are usually used to override resources locally and so 18 | # are not checked in 19 | override.tf 20 | override.tf.json 21 | *_override.tf 22 | *_override.tf.json 23 | 24 | # Include override files you do wish to add to version control using negated pattern 25 | # 26 | # !example_override.tf 27 | 28 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 29 | # example: *tfplan* -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | [![License: Unlicense](https://img.shields.io/badge/license-Unlicense-white.svg)](https://choosealicense.com/licenses/unlicense/) [![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/kunduso/ec2-userdata-terraform)](https://GitHub.com/kunduso/ec2-userdata-terraform/pull/) [![GitHub pull-requests](https://img.shields.io/github/issues-pr/kunduso/ec2-userdata-terraform)](https://GitHub.com/kunduso/ec2-userdata-terraform/pull/) 2 | [![GitHub issues-closed](https://img.shields.io/github/issues-closed/kunduso/ec2-userdata-terraform)](https://github.com/kunduso/ec2-userdata-terraform/issues?q=is%3Aissue+is%3Aclosed) [![GitHub issues](https://img.shields.io/github/issues/kunduso/ec2-userdata-terraform)](https://GitHub.com/kunduso/ec2-userdata-terraform/issues/) 3 | ![Image](https://skdevops.files.wordpress.com/2024/10/103-image-0.png) 4 | ## Motivation 5 | *This GitHub repository contains multiple use cases of working with Terraform to provision Amazon EC2 instances. Specific Git branches separate these use cases. To read more about that, [click here](#other-use-cases-in-this-repository).* 6 | 7 | I came across a use cases where I wanted to install and configure Amazon CloudWatch Logs agent on an Amazon EC2 instance for Linux using Terraform aud the user data script. I updated the logic inside the user data script is to: 8 | 1. Download the Amazon CloudWatch Logs agent installer. 9 | 2. Install the agent. 10 | 3. Download the `config.json` from the SSM Parameter store. 11 | 4. Configure and start the CloudWatch Logs agent service. 12 | 13 | I automated the resource provisioning process using Terraform, my favorite IaC tool. 14 | 15 |
I have supporting documentation on my note at: [install and configure CloudWatch Logs agent on Amazon EC2 instance for Linux using user data.](https://skundunotes.com/2024/10/21/install-and-configure-cloudwatch-logs-agent-on-amazon-ec2-instance-for-linux-using-user-data/) 16 | ## Prerequisites 17 | I installed `terraform` before I worked on this repository. Installation information is available in the [install guide.](https://www.terraform.io/downloads.html)
I used the `access_key` and the `secret_key` of an IAM user that had permission to create all the resources managed via this `terraform` code. 18 |
I created a `terraform.tfvars` file to store them. 19 | 20 | ## Usage 21 | Ensure that the IAM user whose credentials are being used in this configuration has permission to create and manage all the resources that are included in this repository. 22 |
Review the code, especially the `iamrole.tf` and `ec2.tf` file to understand all the concepts associated with creating an IAM role, attaching the role to the AWS managed policy, creating an IAM instance profile with the IAM role and finally attaching the IAM instance profile to the Amazon EC2 instance. 23 |
24 |
Next, run `terraform init` 25 |
Then run `terraform plan` 26 |
And finally run `terraform apply` 27 | 28 | ## Other use-cases in this repository 29 | There are twelve other branches in this repository discussing other use-cases: 30 |
31 |
32 | No.|Use-Case | Branch| 33 | |--- |--- |--- | 34 | |1.|Add an Amazon EC2 instance|https://github.com/kunduso/ec2-userdata-terraform/blob/add-amazon-ec2/ReadMe.md| 35 | |2.|Add a `user_data` script to an Amazon EC2 instance| https://github.com/kunduso/ec2-userdata-terraform/blob/add-userdata/ReadMe.md| 36 | |3.|Attach an AWS IAM role to an Amazon EC2 instance| https://github.com/kunduso/ec2-userdata-terraform/blob/add-iam-role/ReadMe.md| 37 | |4.|Install AWS.Tools module for PowerShell on Amazon EC2 instance running Windows Server using `user_data` script| https://github.com/kunduso/ec2-userdata-terraform/blob/add-aws.tools-powershell-to-userdata/ReadMe.md| 38 | |5.|Install AWS CLI on an Amazon EC2 instance running Windows Server using `user_data` script|https://github.com/kunduso/ec2-userdata-terraform/blob/add-awscli-to-userdata/ReadMe.md| 39 | |6.|Manage sensitive variables in Amazon EC2 with AWS Systems Manager Parameter Store|https://github.com/kunduso/ec2-userdata-terraform/blob/add-ssm-parameter/ReadMe.md| 40 | |7.|Download Amazon S3 bucket contents to Amazon EC2 instance|https://github.com/kunduso/ec2-userdata-terraform/blob/add-s3-access/ReadMe.md| 41 | |8.|Access AWS Secrets Manager secret from Amazon EC2 instance|https://github.com/kunduso/ec2-userdata-terraform/blob/access-secrets-python/ReadMe.md| 42 | |9.|Create an Amazon EC2 instance with Session Manager access|https://github.com/kunduso/ec2-userdata-terraform/blob/add-iam-role-for-session-manager/ReadMe.md| 43 | |10.|Create an Amazon EC2 instance using Terraform with Session Manager access using VPC Endpoint|https://github.com/kunduso/ec2-userdata-terraform/blob/add-vpc-endpoint/ReadMe.md 44 | |11.|Secure RDP Access to Amazon EC2 for Windows: Leveraging Fleet Manager and Session Manager|https://github.com/kunduso/ec2-userdata-terraform/blob/enable-rdp-session-manager/ReadMe.md| 45 | |12.|Install and configure CloudWatch Logs agent on Amazon EC2 instance for Windows using user data|https://github.com/kunduso/ec2-userdata-terraform/blob/add-cloudwatch-agent/ReadMe.md 46 | 47 | ## License 48 | This code is released under the Unlincse License. See [LICENSE](LICENSE). -------------------------------------------------------------------------------- /cloud_watch.tf: -------------------------------------------------------------------------------- 1 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group 2 | resource "aws_cloudwatch_log_group" "logs" { 3 | name = "/${var.name}/ec2/linux" 4 | retention_in_days = 365 5 | kms_key_id = aws_kms_key.custom_kms_key.arn 6 | } -------------------------------------------------------------------------------- /cloudwatch_config/linux_config.json.tftpl: -------------------------------------------------------------------------------- 1 | { 2 | "agent": { 3 | "metrics_collection_interval": 60, 4 | "run_as_user": "root" 5 | }, 6 | "metrics": { 7 | "namespace": "CustomMetrics", 8 | "metrics_collected": { 9 | "cpu": { 10 | "resources": [ 11 | "*" 12 | ], 13 | "measurement": [ 14 | "usage_active", 15 | "usage_idle", 16 | "usage_system", 17 | "usage_user" 18 | ], 19 | "totalcpu": true 20 | }, 21 | "mem": { 22 | "measurement": [ 23 | "used_percent", 24 | "used", 25 | "total" 26 | ] 27 | }, 28 | "disk": { 29 | "resources": [ 30 | "/" 31 | ], 32 | "measurement": [ 33 | "used_percent", 34 | "used", 35 | "total" 36 | ] 37 | }, 38 | "diskio": { 39 | "resources": [ 40 | "*" 41 | ], 42 | "measurement": [ 43 | "reads", 44 | "writes", 45 | "read_bytes", 46 | "write_bytes", 47 | "io_time" 48 | ] 49 | }, 50 | "netstat": { 51 | "measurement": [ 52 | "tcp_established", 53 | "tcp_time_wait" 54 | ] 55 | } 56 | }, 57 | "append_dimensions": { 58 | "InstanceId": "$${aws:InstanceId}", 59 | "AutoScalingGroupName": "$${aws:AutoScalingGroupName}", 60 | "InstanceType": "$${aws:InstanceType}" 61 | }, 62 | "aggregation_dimensions": [ 63 | ["InstanceId"], 64 | ["AutoScalingGroupName"], 65 | ["InstanceType"] 66 | ] 67 | }, 68 | "logs": { 69 | "logs_collected": { 70 | "files": { 71 | "collect_list": [ 72 | { 73 | "file_path": "/var/log/messages", 74 | "log_group_name": "${log_group_name}", 75 | "log_stream_name": "{instance_id}/messages" 76 | }, 77 | { 78 | "file_path": "/var/log/secure", 79 | "log_group_name": "${log_group_name}", 80 | "log_stream_name": "{instance_id}/secure" 81 | }, 82 | { 83 | "file_path": "/var/log/cloud-init.log", 84 | "log_group_name": "${log_group_name}", 85 | "log_stream_name": "{instance_id}/userdatalog" 86 | }, 87 | { 88 | "file_path": "/var/log/cloud-init-output.log", 89 | "log_group_name": "${log_group_name}", 90 | "log_stream_name": "{instance_id}/userdatalog-output" 91 | } 92 | ] 93 | } 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /data.tf: -------------------------------------------------------------------------------- 1 | data "aws_caller_identity" "current" {} 2 | locals { 3 | principal_root_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" 4 | principal_logs_arn = "logs.${var.region}.amazonaws.com" 5 | log_group_arn = "arn:aws:logs:${var.region}:${data.aws_caller_identity.current.account_id}:log-group:/${var.name}/ec2/linux" 6 | } -------------------------------------------------------------------------------- /ec2.tf: -------------------------------------------------------------------------------- 1 | data "aws_ami" "linux_ami" { 2 | filter { 3 | name = "name" 4 | values = ["amzn2-ami-amd-hvm-2.0.20230727.0-x86_64-gp2"] 5 | #values = ["Windows_Server-2019-English-Full-Base-2023*"] // for linux "amzn2-ami-amd-hvm-2.0.20230727.0-x86_64-gp2" 6 | } 7 | filter { 8 | name = "virtualization-type" 9 | values = ["hvm"] 10 | } 11 | most_recent = true 12 | owners = ["amazon"] 13 | } 14 | 15 | resource "aws_instance" "app-server" { 16 | instance_type = "t3.medium" 17 | ami = data.aws_ami.linux_ami.id 18 | vpc_security_group_ids = [aws_security_group.instance-sg.id] 19 | subnet_id = aws_subnet.public.id 20 | associate_public_ip_address = true 21 | iam_instance_profile = aws_iam_instance_profile.ec2_profile.name 22 | metadata_options { 23 | http_endpoint = "enabled" 24 | http_tokens = "required" 25 | http_put_response_hop_limit = 1 26 | instance_metadata_tags = "enabled" 27 | } 28 | user_data = templatefile("user_data/user_data.tpl", 29 | { 30 | Parameter_Name = aws_ssm_parameter.cloudwatch_linux_config.name 31 | }) 32 | tags = { 33 | Name = "${var.name}-server-1" 34 | } 35 | depends_on = [ 36 | aws_kms_key_policy.encrypt_app, 37 | aws_kms_alias.key 38 | ] 39 | } -------------------------------------------------------------------------------- /iamrole.tf: -------------------------------------------------------------------------------- 1 | #Create a role 2 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role 3 | resource "aws_iam_role" "ec2_role" { 4 | name = "${var.name}-ec2-role" 5 | 6 | # Terraform's "jsonencode" function converts a 7 | # Terraform expression result to valid JSON syntax. 8 | assume_role_policy = jsonencode({ 9 | Version = "2012-10-17" 10 | Statement = [ 11 | { 12 | Action = "sts:AssumeRole" 13 | Effect = "Allow" 14 | Sid = "" 15 | Principal = { 16 | Service = "ec2.amazonaws.com" 17 | } 18 | }, 19 | ] 20 | }) 21 | } 22 | 23 | #Attach role to policy 24 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment 25 | resource "aws_iam_role_policy_attachment" "custom" { 26 | role = aws_iam_role.ec2_role.name 27 | policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" 28 | } 29 | 30 | #Attach role to an instance profile 31 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile 32 | resource "aws_iam_instance_profile" "ec2_profile" { 33 | name = "${var.name}-ec2-profile" 34 | role = aws_iam_role.ec2_role.name 35 | } 36 | 37 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy 38 | resource "aws_iam_policy" "custom_policy_ssm" { 39 | name = "${var.name}-custom-policy-ssm" 40 | path = "/" 41 | description = "A policy to allow Linux Amazon EC2 instances to talk with ssm parameters." 42 | 43 | # Terraform's "jsonencode" function converts a 44 | # Terraform expression result to valid JSON syntax. 45 | policy = jsonencode({ 46 | Version = "2012-10-17" 47 | Statement = [ 48 | { 49 | Action = [ 50 | "ssm:GetParameters", 51 | "ssm:GetParameter" 52 | ] 53 | Effect = "Allow" 54 | Resource = "${aws_ssm_parameter.cloudwatch_linux_config.arn}" 55 | }, 56 | { 57 | "Effect" : "Allow", 58 | "Action" : [ 59 | "kms:Decrypt" 60 | ], 61 | "Resource" : "${aws_kms_key.custom_kms_key.arn}" 62 | } 63 | ] 64 | }) 65 | } 66 | 67 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment 68 | resource "aws_iam_role_policy_attachment" "policy_attachment_custom_ssm" { 69 | role = aws_iam_role.ec2_role.name 70 | policy_arn = aws_iam_policy.custom_policy_ssm.arn 71 | } 72 | 73 | resource "aws_iam_role_policy_attachment" "custom_cw_agent" { 74 | role = aws_iam_role.ec2_role.name 75 | policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" 76 | } -------------------------------------------------------------------------------- /kms.tf: -------------------------------------------------------------------------------- 1 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key 2 | resource "aws_kms_key" "custom_kms_key" { 3 | description = "KMS key for ${var.name}" 4 | deletion_window_in_days = 7 5 | enable_key_rotation = true 6 | } 7 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias 8 | resource "aws_kms_alias" "key" { 9 | name = "alias/${var.name}" 10 | target_key_id = aws_kms_key.custom_kms_key.id 11 | } 12 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy 13 | resource "aws_kms_key_policy" "encrypt_app" { 14 | key_id = aws_kms_key.custom_kms_key.id 15 | policy = jsonencode({ 16 | Id = "${var.name}-encryption" 17 | Statement = [ 18 | { 19 | Action = [ 20 | "kms:*" 21 | ] 22 | Effect = "Allow" 23 | Principal = { 24 | AWS = "${local.principal_root_arn}" 25 | } 26 | Resource = "*" 27 | Sid = "Enable IAM User Permissions" 28 | }, 29 | { 30 | Effect = "Allow", 31 | Principal = { 32 | Service = "ssm.amazonaws.com" 33 | }, 34 | Action = [ 35 | "kms:Encrypt*", 36 | "kms:Decrypt*", 37 | "kms:ReEncrypt*", 38 | "kms:GenerateDataKey*", 39 | "kms:Describe*" 40 | ], 41 | Resource = "*", 42 | Condition = { 43 | StringEquals = { 44 | "kms:ViaService" = "ssm.${var.region}.amazonaws.com" 45 | } 46 | } 47 | }, 48 | { 49 | Effect : "Allow", 50 | Principal : { 51 | Service : "${local.principal_logs_arn}" 52 | }, 53 | Action : [ 54 | "kms:Encrypt*", 55 | "kms:Decrypt*", 56 | "kms:ReEncrypt*", 57 | "kms:GenerateDataKey*", 58 | "kms:Describe*" 59 | ], 60 | Resource : "*", 61 | Condition : { 62 | ArnEquals : { 63 | "kms:EncryptionContext:aws:logs:arn" : [local.log_group_arn] 64 | } 65 | } 66 | } 67 | ] 68 | Version = "2012-10-17" 69 | }) 70 | } -------------------------------------------------------------------------------- /provider.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | aws = { 4 | source = "hashicorp/aws" 5 | version = "5.26.0" 6 | } 7 | } 8 | } 9 | provider "aws" { 10 | region = var.region 11 | access_key = var.access_key 12 | secret_key = var.secret_key 13 | default_tags { 14 | tags = { 15 | Source = "https://github.com/kunduso/ec2-userdata-terraform" 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /security_group.tf: -------------------------------------------------------------------------------- 1 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_security_group 2 | resource "aws_default_security_group" "default" { 3 | vpc_id = aws_vpc.this.id 4 | } 5 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group 6 | resource "aws_security_group" "instance-sg" { 7 | name = "${var.name}-ec2-access" 8 | description = "allow traffic to the ec2 instance" 9 | vpc_id = aws_vpc.this.id 10 | tags = { 11 | "Name" = "${var.name}-ec2-sg" 12 | } 13 | } 14 | #https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule 15 | resource "aws_security_group_rule" "egress_instance_sg" { 16 | description = "allow traffic from the vpc to reach outside the vpc" 17 | type = "egress" 18 | from_port = 0 19 | to_port = 0 20 | protocol = "-1" 21 | cidr_blocks = ["0.0.0.0/0"] 22 | security_group_id = aws_security_group.instance-sg.id 23 | } -------------------------------------------------------------------------------- /ssm_parameter.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | config_json = templatefile("${path.module}/cloudwatch_config/linux_config.json.tftpl", { 3 | log_group_name = aws_cloudwatch_log_group.logs.name 4 | }) 5 | } 6 | resource "aws_ssm_parameter" "cloudwatch_linux_config" { 7 | name = "/${var.name}/Amazon-CloudWatch-Linux-Config" 8 | type = "SecureString" 9 | key_id = aws_kms_key.custom_kms_key.id 10 | value = local.config_json 11 | } -------------------------------------------------------------------------------- /user_data/user_data.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Update the instance 3 | yum update -y 4 | if [ $? -eq 0 ]; then 5 | echo "Updated the instance successfully." 6 | else 7 | echo "Failed to update the instance." 8 | exit 1 9 | fi 10 | 11 | # Install the CloudWatch Agent 12 | yum install -y amazon-cloudwatch-agent 13 | if [ $? -eq 0 ]; then 14 | echo "Installed Amazon CloudWatch Agent." 15 | else 16 | echo "Failed to install Amazon CloudWatch Agent." 17 | exit 1 18 | fi 19 | 20 | # Creates token to authenticate and retrieve instance metadata 21 | TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") 22 | if [ $? -eq 0 ]; then 23 | echo "Created token for instance metadata." 24 | else 25 | echo "Failed to create token." 26 | exit 1 27 | fi 28 | 29 | # Set the AWS region using the token 30 | AWS_REGION=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/placement/region) 31 | if [ $? -eq 0 ]; then 32 | export AWS_DEFAULT_REGION=$AWS_REGION 33 | echo "Setting AWS Region to: $AWS_DEFAULT_REGION" 34 | else 35 | echo "Failed to fetch AWS region." 36 | exit 1 37 | fi 38 | 39 | # Fetch CloudWatch agent configuration from SSM Parameter Store 40 | CONFIG=$(aws ssm get-parameter --name "${Parameter_Name}" --with-decryption --query "Parameter.Value" --output text) 41 | if [ $? -eq 0 ]; then 42 | echo "Fetched CloudWatch agent configuration." 43 | else 44 | echo "Failed to fetch CloudWatch agent configuration." 45 | exit 1 46 | fi 47 | 48 | # Save the configuration to a file 49 | echo $CONFIG > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json 50 | if [ $? -eq 0 ]; then 51 | echo "Saved CloudWatch agent configuration to file." 52 | else 53 | echo "Failed to save CloudWatch agent configuration." 54 | exit 1 55 | fi 56 | 57 | # Start the CloudWatch agent with the new configuration 58 | /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json 59 | if [ $? -eq 0 ]; then 60 | echo "Started CloudWatch agent with new configuration." 61 | else 62 | echo "Failed to start CloudWatch agent." 63 | exit 1 64 | fi 65 | 66 | # Ensure the CloudWatch agent starts on system boot 67 | systemctl enable amazon-cloudwatch-agent 68 | if [ $? -eq 0 ]; then 69 | echo "Configured CloudWatch agent to start on boot." 70 | else 71 | echo "Failed to enable CloudWatch agent on boot." 72 | exit 1 73 | fi -------------------------------------------------------------------------------- /variable.tf: -------------------------------------------------------------------------------- 1 | variable "access_key" { 2 | type = string 3 | default = "" 4 | sensitive = true 5 | } 6 | variable "secret_key" { 7 | type = string 8 | default = "" 9 | sensitive = true 10 | } 11 | variable "region" { 12 | type = string 13 | default = "us-east-2" 14 | } 15 | variable "name" { 16 | description = "The name of the application." 17 | type = string 18 | default = "app-1" 19 | } 20 | variable "vpc_cidr" { 21 | description = "CIDR for the VPC." 22 | default = "10.20.20.0/25" 23 | type = string 24 | } 25 | variable "subnet_cidr_public" { 26 | description = "CIDR blocks for the public subnet." 27 | default = "10.20.20.64/26" 28 | type = string 29 | } -------------------------------------------------------------------------------- /vpc.tf: -------------------------------------------------------------------------------- 1 | resource "aws_vpc" "this" { 2 | cidr_block = var.vpc_cidr 3 | tags = { 4 | "Name" = "${var.name}" 5 | } 6 | } 7 | resource "aws_subnet" "public" { 8 | vpc_id = aws_vpc.this.id 9 | cidr_block = var.subnet_cidr_public 10 | availability_zone = "us-east-2a" 11 | tags = { 12 | "Name" = "${var.name}-public" 13 | } 14 | } 15 | resource "aws_route_table" "this-rt" { 16 | vpc_id = aws_vpc.this.id 17 | tags = { 18 | "Name" = "${var.name}-route-table" 19 | } 20 | } 21 | resource "aws_route_table_association" "public" { 22 | subnet_id = aws_subnet.public.id 23 | route_table_id = aws_route_table.this-rt.id 24 | } 25 | resource "aws_internet_gateway" "this-igw" { 26 | vpc_id = aws_vpc.this.id 27 | tags = { 28 | "Name" = "${var.name}-gateway" 29 | } 30 | } 31 | resource "aws_route" "internet-route" { 32 | destination_cidr_block = "0.0.0.0/0" 33 | route_table_id = aws_route_table.this-rt.id 34 | gateway_id = aws_internet_gateway.this-igw.id 35 | } --------------------------------------------------------------------------------