in tflint-ruleset-aws-serverless/rules/aws_cloudwatch_log_group_lambda_retention.go [60:184]
func (r *AwsCloudwatchLogGroupLambdaRetentionRule) Check(runner tflint.Runner) error {
// Gather all Lambda functions
var functions []awsLambdaLogGroup
err := runner.WalkResources(r.functionResourceType, func(resource *configs.Resource) error {
function := awsLambdaLogGroup{
resourceName: resource.Name,
functionName: "",
found: false,
resourceRange: resource.Config.MissingItemRange(),
}
// Function name attribute
body, _, diags := resource.Config.PartialContent(&hcl.BodySchema{
Attributes: []hcl.AttributeSchema{
{
Name: r.functionNameAttrName,
},
},
})
if diags.HasErrors() {
return diags
}
attribute, ok := body.Attributes[r.functionNameAttrName]
if ok {
var value string
err := runner.EvaluateExpr(attribute.Expr, &value, nil)
if err != nil {
return err
}
function.functionName = value
}
functions = append(functions, function)
return nil
})
if err != nil {
return err
}
// Lookup log groups
err = runner.WalkResources(r.logGroupResourceType, func(resource *configs.Resource) error {
body, _, diags := resource.Config.PartialContent(&hcl.BodySchema{
Attributes: []hcl.AttributeSchema{
{
Name: r.nameAttrName,
},
{
Name: r.retentionAttrName,
},
},
})
if diags.HasErrors() {
return diags
}
// Get log group attributes
nameAttr, ok := body.Attributes[r.nameAttrName]
// No need to check further if there are no name, early return
if !ok {
return nil
}
var nameValue string
err := runner.EvaluateExpr(nameAttr.Expr, &nameValue, nil)
if err != nil {
return err
}
retentionAttr, ok := body.Attributes[r.retentionAttrName]
// No need to check further if there are no retention, early return
if !ok {
return nil
}
var retentionValue string
err = runner.EvaluateExpr(retentionAttr.Expr, &retentionValue, nil)
if err != nil {
return err
}
// Parse log group names
re := regexp.MustCompile(`^/aws/lambda/(.*)$`)
m := re.FindAllStringSubmatch(nameValue, -1)
// Log group name doesn't match pattern, early return
if len(m) > 1 {
return nil
}
functionName := m[0][1]
for i := range functions {
if functions[i].functionName == functionName {
functions[i].found = true
}
if fmt.Sprintf("${aws_lambda_function.%s.function_name}", functions[i].resourceName) == functionName {
functions[i].found = true
}
}
return nil
})
if err != nil {
return err
}
for _, function := range functions {
if !function.found {
runner.EmitIssue(
r,
fmt.Sprintf("\"%s\" is missing a log group with retention_in_days.", r.functionResourceType),
function.resourceRange,
)
}
}
return nil
}