2017-05-22 223 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