-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlambda_deploy.go
140 lines (127 loc) · 4.16 KB
/
lambda_deploy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package lambda_deploy
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/lambda"
"github.com/mitchellh/go-homedir"
"fmt"
"strings"
"io/ioutil"
"log"
"github.com/aws/aws-sdk-go/aws/awserr"
"crypto/sha256"
"encoding/base64"
)
func LambdaDeploy(profile, region, zipfile string, descriptor *LambdaFunctionDesc) {
svc := SetupLambdaClient(profile, region)
getFunctionInput := lambda.GetFunctionInput{FunctionName: &(descriptor.Function_name)}
result, err := svc.GetFunction(&getFunctionInput)
if checkIfLambdaIsDeployed(err) {
fmt.Println("The function already exists")
amazonSha := *(result.Configuration.CodeSha256)
if amazonSha == Base64sha256(zipfile) {
fmt.Println("Your zipfile and the uploaded one are identical")
} else {
fmt.Println("Uploading lambda function")
updateExistingCode(svc, descriptor, zipfile)
}
configDiff, isDifferent := descriptor.CompareConfig(result.Configuration)
if !isDifferent {
fmt.Println("Config is unchanged - will not update")
} else {
fmt.Println("Config is changed - differences:", configDiff)
result, err := svc.UpdateFunctionConfiguration(configDiff)
check(err)
fmt.Println("Config has been updated, it is now:", result)
}
} else {
fmt.Println("Lambda function is not deployed")
createNewLambda(svc, descriptor, zipfile)
}
}
func checkIfLambdaIsDeployed(getFunctionError error) (bool) {
if getFunctionError == nil {
return true
} else {
if strings.Contains(getFunctionError.Error(), "ResourceNotFoundException") {
return false
} else {
panic(getFunctionError)
}
}
}
func createNewLambda(client *lambda.Lambda, descriptor *LambdaFunctionDesc, zipfile string) {
file, zipErr := loadFileContent(zipfile)
if zipErr != nil {
panic(fmt.Errorf("Unable to load %q: %s", zipfile, zipErr))
}
functionCode := lambda.FunctionCode {
ZipFile: file,
}
params := &lambda.CreateFunctionInput{
Code: &functionCode,
Description: aws.String(descriptor.Description),
FunctionName: aws.String(descriptor.Function_name),
Handler: aws.String(descriptor.Handler),
MemorySize: aws.Int64(int64(descriptor.Memory_size)),
Role: aws.String(descriptor.Role),
Runtime: aws.String(descriptor.Runtime),
Timeout: aws.Int64(int64(descriptor.Timeout)),
Publish: aws.Bool(descriptor.Publish),
}
if len(descriptor.Environment) > 0 {
params.Environment = &lambda.Environment{
Variables: aws.StringMap(descriptor.Environment),
}
}
if descriptor.Vpc_config != nil {
params.VpcConfig = &lambda.VpcConfig{
SecurityGroupIds: aws.StringSlice(descriptor.Vpc_config.Security_group_ids),
SubnetIds: aws.StringSlice(descriptor.Vpc_config.Subnet_ids),
}
}
fmt.Println("Uploading lambda function")
_, err := client.CreateFunction(params)
if err != nil {
log.Printf("[ERROR] Received %q", err)
if awserr, ok := zipErr.(awserr.Error); ok {
if awserr.Code() == "InvalidParameterValueException" {
log.Printf("[DEBUG] InvalidParameterValueException creating Lambda Function: %s", awserr)
}
}
log.Printf("[DEBUG] Error creating Lambda Function: %s", err)
panic(err)
}
}
func updateExistingCode(client *lambda.Lambda, descriptor *LambdaFunctionDesc, zipfile string) {
file, err := loadFileContent(zipfile)
check(err)
input := &lambda.UpdateFunctionCodeInput{
FunctionName: aws.String(descriptor.Function_name),
Publish: aws.Bool(descriptor.Publish),
ZipFile: file,
}
result, err := client.UpdateFunctionCode(input)
check(err)
fmt.Println("Result of code update:", result)
}
// see: https://github.com/hashicorp/terraform/blob/master/builtin/providers/aws/resource_aws_lambda_function.go
func loadFileContent(v string) ([]byte, error) {
filename, err := homedir.Expand(v)
if err != nil {
return nil, err
}
fileContent, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return fileContent, nil
}
// Generates a base64 sha 256 string from a file in order to check if it is
// Different from the one that is on AWS.
func Base64sha256 (zipfile string) (string) {
file, _ := loadFileContent(zipfile)
h := sha256.New()
h.Write(file)
shaSum := h.Sum(nil)
return base64.StdEncoding.EncodeToString(shaSum[:])
}