Trying to deploy multiple lambda functions through terraform but getting error message. i have the lambda code in the s3 bucket. below is my code.
Error: Unbalanced parentheses on main.tf , in resource "aws_lambda_function" "test_lambda": function_name = (for fname in var.lambda_function_names: fname.split(".")[0] if fname == var.lambda_function_names[count.index]) Expected a closing parenthesis to terminate the expression.
variable "lambda_function_names"{
default = [
"test1.py",
"test2.py"
]
}
resource "aws_lambda_function" "test_lambda" {
count = length(var.lambda_function_names) > 0 ? length(var.lambda_function_names) : 0
s3_bucket="test-bucket"
s3_key= "lambda_source_code/${var.lambda_function_names[count.index]}"
function_name = for fname in var.lambda_function_names: fname.split(".")[0] if fname == var.lambda_function_names[count.index])
role = "arn:aws:iam::12344566676:role/lambda-role"
handler = "${var.lambda_function_names[count.index]}.lambda_handler"
runtime = "python3.8"
}
Related
server version: 2.00.8 2022.09.28
I define a function myFunc in DolphinDB as follows. The definition part and each line of code in the function body can be executed successfully. But error occurs when the script is run:
Server response: 'myFunc("20230118", t) => myFunc: tmp = select * from t where date(dt) == date => The object date is neither a XDB connection nor a function definition.'
dt = 2023.01.18T04:01:51.100 2023.01.19T04:01:51.000 2023.01.19T04:01:51.900
sym = ["IBM", "MSFTN", "GOOGS"]
value = 1..3
t=table(dt, sym, value)
def myFunc(day, t){
date = temporalParse(day, "yyyyMMdd")
tmp = select * from t where date(dt)=date
return tmp
}
myFunc("20230118", t)
It works after just replaced the variable date to dateParsed:
def myFunc(day, t){
dateParsed = temporalParse(day, "yyyyMMdd")
tmp = select * from t where date(dt)=dateParsed
return tmp
}
The error is reported because a variable named “date” is defined in the function body, and the built-in function date is called later. When the function is parsed, date(dt) cannot be recognized as a function as the variable is parsed first. Thus it is not recommended to define variables with the same name as built-in functions or other keywords.
The script can be corrected to:
def myFunc(day, t){
myDate = temporalParse(day, "yyyyMMdd")
tmp = select * from t where date(dt)=myDate
return tmp
}
myFunc("20230118", t)
Hi I am trying to run a schedule script, not via lambda but from a pc or onsite schedule job - maybe every 10 mins or so to check all my ec2 instances are failing any system/instance status checks. If it fails then send email of the ec2 instance that failing - just send the name. Do not reboot
so here is what i have
import boto3
import smtplib
region_name='us-west-1'
#ec2_client = boto3.client('ec2')
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
#response = ec2_client.describe_instance_status(IncludeAllInstances = True)
client = boto3.client("ec2")
clientsns = boto3.client("sns")
#response = clientsns.create_topic
status = client.describe_instance_status(IncludeAllInstances = True)
#for instance in response['InstanceStatuses']:
# instance_id = instance['InstanceId']
# system_status = instance['SystemStatus']
# instance_status = instance['InstanceStatus']
# print (instance_id, system_status, instance_status)
for i in status["InstanceStatuses"]:
print("AvailabilityZone :", i["AvailabilityZone"])
print("InstanceId :", i["InstanceId"])
print("InstanceState :", i["InstanceState"])
print("InstanceStatus", i["InstanceStatus"])
print("SystemStatus", i["SystemStatus"])
in_status = i['InstanceStatus']['Details'][0]['Status']
sys_status = i['SystemStatus']['Details'][0]['Status']
msg1 = 'The following instances failed status checks, i[{InstanceId}]'
msg2 = 'All Instances passed System/instance checks!'
# check statuses
if ((in_status != 'passed') or (sys_status != 'passed')):
print(bcolors.WARNING + 'Reboot required for', i["InstanceId"] + bcolors.ENDC)
clientsns.publish(TopicArn='arn:aws:sns:us-west-1:462518063038:test',Message=msg1)
else:
print('All Instances passed System/instance checks!')
clientsns.publish(TopicArn='arn:aws:sns:us-west-1:462518063038:test',Message=msg2)
The problem I have is its sending one message per instance. I just wwant to sent one email for all instances. any idea?
Thank you
Terraform variable validation using length function
Getting error while using length function & substr for vswitch_ids
Condition - vswitch_name value must start with vsw-
variable "vswitch_ids" {
description = "The vswitch IDs."
type = list(string)
validation {
condition = (
length(var.vswitch_ids) > 0 &&
substr(var.switch_ids, 0, 4) == "vsw-"
)
error_message = "The vswitch_name value must start with \"vsw-\"."
}
}
Error: Invalid function argument
on modules/k8s/variables.tf line 34, in variable "vswitch_ids":
34: substr(var.vswitch_ids, 0, 4) == "vsw-"
|----------------
| var.vswitch_ids is list of string with 3 elements
Invalid value for "str" parameter: string required.
The following should work. It will check if all elements in your variable list start with vsw:
variable "vswitch_ids" {
description = "The vswitch IDs."
type = list(string)
validation {
condition = (
length(var.vswitch_ids) > 0 &&
length([for v in var.vswitch_ids: 1 if substr(v, 0, 4) == "vsw-"]) == length(var.vswitch_ids)
)
error_message = "The vswitch_name value must start with \"vsw-\"."
}
}
I have the following random_test.tf Terraform file, which I've successfully initialized:
resource "random_integer" "octet" {
min = 0
max = 255
}
variable "base_cidr_block" {
description = "Class A CIDR block in RFC 1918 range"
default = "10.0.0.0/8"
}
provider "null" {
base_cidr_block = "10.${random_integer.octet.result}.0.0/16"
}
output "ip_block" {
value = var.base_cidr_block
}
I'm using the null provider as a placeholder to test defining a 10.0.0.0/16 CIDR block with a random second octet. However, base_cidr_block is always 10.0.0.0/8 even though I'm expecting it to be assigned something like 10.100.0.0/16, which would then be shown on standard output as ip_block. Instead, I always get the default:
$ terraform plan
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# random_integer.octet will be created
+ resource "random_integer" "octet" {
+ id = (known after apply)
+ max = 255
+ min = 0
+ result = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ ip_block = "10.0.0.0/8"
Running terraform apply then always sends ip_block = "10.0.0.0/8" to the console. What am I doing wrong?
Here's what I've come up with, although I may not understand the intent.
First, I've created a module. I'm using the random_integer, and setting a keeper:
variable "netname" {
default = "default"
}
variable "subnet" {
default = "10.0.0.0/8"
}
resource "random_integer" "octet" {
min = 0
max = 255
keepers = {
netname = var.netname
}
}
output "rand" {
value = random_integer.octet.result
}
output "random-subnet" {
value = "${cidrsubnet("${var.subnet}", 8, random_integer.octet.result)}"
}
Next I call the module, passing in my keeper, and optionally the subnet:
module "get-subnet-1" {
source = "./module/"
netname = "subnet-1"
}
output "get-subnet-1" {
value = module.get-subnet-1.random-subnet
}
module "get-subnet-2" {
source = "./module/"
netname = "subnet-2"
}
output "get-subnet-2" {
value = module.get-subnet-2.random-subnet
}
Finally, my output:
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
get-subnet-1 = 10.2.0.0/16
get-subnet-2 = 10.6.0.0/16
I ran the code at the bottom of this post in my environment and got the following error after a few successes:
An error occurred (SnapshotCreationPerVolumeRateExceeded) when calling the CreateSnapshot operation: The maximum per volume CreateSnapshot request rate has been exceeded. Use an increasing or variable sleep interval between requests.
I'm used to doing something like this to paginate my results using a MaxResults variable and the NextToken returned by the response:
maxResults = 100
result = ec2.describe_instances(MaxResults=maxResults)
nextToken = result['NextToken']
instance_ids = []
for reservation in result['Reservations']:
for instances in reservation['Instances']:
for i in instances:
instance_ids.append(i['InstanceId'])
size = len(instance_ids)
while size == maxResults:
result = ec2.describe_instances(MaxResults=maxResults, NextToken=nextToken)
nextToken = result['NextToken']
size = len(instance_ids)
# etc...
However, because I'm already filtering by tag in my describe_instances call, I'm not allowed to pass a maxResults parameter as well. Additionally, create_snapshot's call signature only allows me to specify a dry run, the volume ID, and a description of the snapshot, and does not return a nextToken or similar. How can I avoid this error - must I introduce a sleep like the error message suggests?
Lambda function code:
from __future__ import print_function
import boto3
import datetime
import time
ec2 = boto3.client('ec2')
def createScheduleSnapshots(event, context):
errors = []
try:
print("Creating snapshots on " + str(datetime.datetime.today()) + ".")
schedulers = ec2.describe_instances(Filters=[{'Name':'tag:GL-sub-purpose', 'Values':['Schedule']}])
schedule_instances = []
for reservation in schedulers['Reservations']:
for instance in reservation['Instances']:
schedule_instances.append(instance)
print("Performing backup on " + str(len(schedule_instances)) + " schedules.")
successful = []
failed = []
for s in schedule_instances:
try:
instanceId=s['InstanceId']
blockDeviceMappings = s['BlockDeviceMappings']
snapshotDescription = instanceId + "-" + str(datetime.date.today().strftime('%Y-%m-%d')) + "-46130e7ac954-automated"
for bd_maps in blockDeviceMappings:
if (bd_maps['DeviceName'] == '/dev/sdf'): #Don't back up OS
volumeId = bd_maps['Ebs']['VolumeId']
print("\tSnapshotting " + instanceId)
ec2.create_snapshot(
VolumeId=volumeId,
Description=snapshotDescription
)
successful.append(instanceId)
except Exception as e:
print(e)
errors.append(e)
failed.append(instanceId + " :\t" + str(e))
print("Performed backup on " + str(len(successful)) + " schedulers. Failed backup on " + str(len(failed)) + " schedulers. ")
except Exception as e:
print(e)
errors.append(e)
if len(errors) == 0:
return "Success"
else:
raise Exception("Errors during invocation of Lambda. " + str(errors))