-
-
Save wshihadeh/e13ed919e11031ae9c2e417da2ffa904 to your computer and use it in GitHub Desktop.
resource "aws_iam_policy" "stop_start_ec2_policy" { | |
name = "StopStartEC2Policy" | |
path = "/" | |
description = "IAM policy for stop and start EC2 from a lambda" | |
policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Action": [ | |
"logs:CreateLogGroup", | |
"logs:CreateLogStream", | |
"logs:PutLogEvents" | |
], | |
"Resource": "arn:aws:logs:*:*:*" | |
}, | |
{ | |
"Effect": "Allow", | |
"Action": [ | |
"ec2:Start*", | |
"ec2:Stop*", | |
"ec2:DescribeInstances*" | |
], | |
"Resource": "*" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_iam_role" "stop_start_ec2_role" { | |
name = "StopStartEC2Role" | |
assume_role_policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Action": "sts:AssumeRole", | |
"Principal": { | |
"Service": "lambda.amazonaws.com" | |
}, | |
"Effect": "Allow", | |
"Sid": "" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_iam_role_policy_attachment" "lambda_role_policy" { | |
role = "${aws_iam_role.stop_start_ec2_role.name}" | |
policy_arn = "${aws_iam_policy.stop_start_ec2_policy.arn}" | |
} | |
resource "aws_lambda_function" "stop_ec2_lambda" { | |
filename = "ec2_lambda_handler.zip" | |
function_name = "stopEC2Lambda" | |
role = "${aws_iam_role.stop_start_ec2_role.arn}" | |
handler = "ec2_lambda_handler.stop" | |
source_code_hash = "${filebase64sha256("ec2_lambda_handler.zip")}" | |
runtime = "python3.7" | |
memory_size = "250" | |
timeout = "60" | |
} | |
resource "aws_cloudwatch_event_rule" "ec2_stop_rule" { | |
name = "StopEC2Instances" | |
description = "Stop EC2 nodes at 19:00 from Monday to friday" | |
schedule_expression = "cron(0 19 ? * 2-6 *)" | |
} | |
resource "aws_cloudwatch_event_target" "ec2_stop_rule_target" { | |
rule = "${aws_cloudwatch_event_rule.ec2_stop_rule.name}" | |
arn = "${aws_lambda_function.stop_ec2_lambda.arn}" | |
} | |
resource "aws_lambda_permission" "allow_cloudwatch_stop" { | |
statement_id = "AllowExecutionFromCloudWatch" | |
action = "lambda:InvokeFunction" | |
function_name = "${aws_lambda_function.stop_ec2_lambda.function_name}" | |
principal = "events.amazonaws.com" | |
} | |
resource "aws_lambda_function" "start_ec2_lambda" { | |
filename = "ec2_lambda_handler.zip" | |
function_name = "startEC2Lambda" | |
role = "${aws_iam_role.stop_start_ec2_role.arn}" | |
handler = "ec2_lambda_handler.start" | |
source_code_hash = "${filebase64sha256("ec2_lambda_handler.zip")}" | |
runtime = "python3.7" | |
memory_size = "250" | |
timeout = "60" | |
} | |
resource "aws_cloudwatch_event_rule" "ec2_start_rule" { | |
name = "StartEC2Instances" | |
description = "Start EC2 nodes at 6:30 from Monday to friday" | |
schedule_expression = "cron(30 6 ? * 2-6 *)" | |
} | |
resource "aws_cloudwatch_event_target" "ec2_start_rule_target" { | |
rule = "${aws_cloudwatch_event_rule.ec2_start_rule.name}" | |
arn = "${aws_lambda_function.start_ec2_lambda.arn}" | |
} | |
resource "aws_lambda_permission" "allow_cloudwatch_start" { | |
statement_id = "AllowExecutionFromCloudWatch" | |
action = "lambda:InvokeFunction" | |
function_name = "${aws_lambda_function.start_ec2_lambda.function_name}" | |
principal = "events.amazonaws.com" | |
} |
You need to create a terraform project first and move the above code to main.tf and add also the provider and var files
commands to apply to terraform
terraform init -backend-config="${Your_vars_file}"
terraform plan -var-file="${Your_vars_file}" -lock=false
terraform apply
commands to run the above code
# config
terraform init -backend-config="${Your_vars_file}";
terraform init -var-file="${Your_vars_file}";
zip ec2_lambda_handler.zip ec2_lambda_handler.py
#apply
terraform apply -var-file="${Your_vars_file}"
#destory
terraform destroy -var-file="${Your_vars_file}"
Thank you so much for providing this. I am new to terraform can you please share your variables.tf?
it could be something like
variable "region" {
type = "string"
description = "Create an ec2 instacne in a given region"
}
variable "ami" {
type = "string"
description = "Image ami id"
}
variable "instance_type" {
type = "string"
description = "Instance type"
}
variable "instance_name" {
type = "string"
description = "Name to be used on all resources as prefix"
}
variable "name" {
type = "string"
description = "Name of all the resources"
}
variable "instance_count" {
description = "Number of instances to launch"
type = number
default = 1
}
variable "profile" {
default = "terraform"
description = "Using terraform for deployment"
}
and you may need another file for the values of these vars
region="eu-central-1"
ami="ami-dd3c0f36"
instance_type="t2.xlarge"
instance_name="dev01-docker01"
instance_count=1
instance_size="100"
You are a life saver!! We are implementing it in our dev environment. Let say if I would like to use different tags based on the region to make more functional. Obviously I would have to add the necessary code to the main.tf by updating the time but I am scratching my head on the lambda part a I am new to it. I would appreciate any feedback you have hero. See my code below :
import boto3
region = 'us-gov-west-1'
ec2 = boto3.client('ec2', region_name=region)
response = ec2.describe_instances(Filters=[
{
'Name': 'tag:Auto-Start-EST',
'Values': [
'true',
'Name': 'tag:Auto-Start-MST',
'Values': [
'true',
'Name': 'tag:Auto-Start-PST',
'Values': [
'true',
]
},
])
instances = []
for reservation in response["Reservations"]:
for instance in reservation["Instances"]:
instances.append(instance["InstanceId"])
def stop(event, context):
ec2.stop_instances(InstanceIds=instances)
print('stopped instances: ' + str(instances))
def start(event, context):
ec2.start_instances(InstanceIds=instances)
print('started instances: ' + str(instances))
Never mind my question. To make things simpler I will just create a module for each region (EST, PST, MST) with their respective variables and output tfs. Thoughts!!! ;)
it seems that you have a syntax issue here, you are missing couple of ]
response = ec2.describe_instances(Filters=[
{
'Name': 'tag:Auto-Start-EST',
'Values': [
'true',
'Name': 'tag:Auto-Start-MST',
'Values': [
'true',
'Name': 'tag:Auto-Start-PST',
'Values': [
'true',
]
},
])
Can you please provide for the Azure too to Start and stop the VM's
Can you also provide the steps to run this? I have a python file with stop and start code, I have downloaded terraform on my machine.. Can you please share the steps to stop or start any instance, please?