2017-05-22 228 views
1

我想创建一个可调用lambda(@edge)的CloudFront分配。我能够使用AWS控制台执行此操作。我现在正在尝试使用Terraform实现相同的功能。我的配置如下。通过Terraform创建CloudFront分配时InvalidLambdaFunctionAssociation

首先,我为lambda创建了一个角色。

resource "aws_iam_role" "my_edge_lambda_iam_role" { 
    name = "my_edge_lambda_iam_role" 

    assume_role_policy = <<EOF 
{ 
    "Version": "2012-10-17", 
    "Statement": [ 
    { 
     "Action": "sts:AssumeRole", 
     "Principal": { 
     "Service": "lambda.amazonaws.com" 
     }, 
     "Effect": "Allow", 
     "Sid": "" 
    } 
    ] 
} 
EOF 
} 

接下来,我创建了一个lambda。

resource "aws_lambda_function" "redirect_lambda" { 
    filename   = "myscript.js.zip" 
    function_name = "my_js_script" 
    role    = "arn:aws:iam::123456789:role/my_edge_lambda_iam_role" 
    handler   = "index.handler" 
    runtime   = "nodejs4.3-edge" 
} 

最后,我(试图)使用上面的lambda函数的ARN创建了CloudFront分布。定义如下。

resource "aws_cloudfront_distribution" "s3_distribution" { 
    origin { 
    domain_name = "my-bucket.s3.amazonaws.com" 
    origin_id = "<my S3 path>" 
    } 

    enabled    = true 
    is_ipv6_enabled  = true 

    default_cache_behavior { 
    allowed_methods = ["GET", "HEAD"] 
    cached_methods = ["GET", "HEAD"] 
    target_origin_id = "<my target origin>" 

    forwarded_values { 
     query_string = false 

     cookies { 
     forward = "none" 
     } 
    } 

    lambda_function_association { 
     event_type = "viewer-request" 
     lambda_arn = "<arn of the lambda function denerated above>" 
    } 

    viewer_protocol_policy = "allow-all" 
    min_ttl    = 0 
    default_ttl   = 86400 
    max_ttl    = 31536000 
    } 

    price_class = "PriceClass_All" 

    viewer_certificate { 
    cloudfront_default_certificate = true 
} 

    restrictions { 
    geo_restriction { 
     restriction_type = "none" 
    } 
    } 
} 

当试图创建分配时,我得到以下异常。

Error applying plan: 

1 error(s) occurred: 

* aws_cloudfront_distribution.s3_distribution: 1 error(s) occurred: 

* aws_cloudfront_distribution.s3_distribution: InvalidLambdaFunctionAssociation: Failed to retrieve the function from Lambda. ErrorCode: AccessDeniedException Function: arn:aws:lambda:us-east-2:12345678:function:my_js_script 
    status code: 400, request id: 65579sd33-3f2d5-181e7-9140-79c1ff79fbdd 

难道这是我如何定义角色的问题吗?

+2

目前尚不清楚如何做到这一点与Terraform工作,但似乎有是要求告诉“lambda”,“edgelambda”被允许获取函数......这是对函数本身的许可(不是角色)(我认为)(也许)... http://docs.aws .amazon.com/lambda/latest/dg/lambda-edge.html#lambda-edge-permissions –

+0

@ Michael-sqlbot:是否有一个示例Terraform配置如何向lambda添加权限? – Nik

回答

3

由于comments中提到的Michael,您需要添加一个aws_lambda_permission资源以允许AWS服务调用Lambda函数。

resource "aws_lambda_permission" "allow_cloudfront" { 
    statement_id = "AllowExecutionFromCloudFront" 
    action   = "lambda:GetFunction" 
    function_name = "${aws_lambda_function.redirect_lambda.function_name}" 
    principal  = "edgelambda.amazonaws.com" 
} 

AWS docs对如何让这个Terraform之外,在这种情况下使用CLI多一点信息:

aws lambda add-permission \    
--function-name arn \ 
--statement-id statement-id \ 
--action lambda:GetFunction \ 
--principal edgelambda.amazonaws.com