Terraform 进阶 - 部署 Lambda 并创建相关资源
昨日刚刚体验了 Terraform 是一个什么鬼东西 Terraform 使用 - 从最简单例子开始,今天再进一步。将来尝试的是使用 Terraform 来部署一个 Lambda 应用,并创建相关的资源。
本例中的 Lambda 要由 Kinesis 来触发,并写数据到 S3 Bucket 中去,所以需要做的事情大致如下:
以下是 Lambda 的实现代码,从 Kinesis 读出字符串,逗号分割,第一部分作为 S3 Key, 第二部分作为文件内容写入到 S3 Bucket 中去。S3 Bucket 名称从环境变量中读取。
接下来的事情全部要交给 Terraform 来完成了,在于怎么写那个 tf 文件,为方便起见我们直接在这个 Java 项目根目录下创建一个
由于贴代码有些问题,所以直接截的图。
现在一切准备就绪,可以登陆到 AWS 的控制台看下 Terraform 是不是为我们创建好了应有的东西。一切正常的就可以发送 Kinesis 消息到我们新创建的 Kinesis Stream 了,看看在 Bucket 里是不是有了 Lambda 生成的文件。
上面创建的东西不想要了,想统统干掉,那就更简单了
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
本例中的 Lambda 要由 Kinesis 来触发,并写数据到 S3 Bucket 中去,所以需要做的事情大致如下:
- 创建 IAM Role, 该 Role 要能访问 S3, Kinesis 和 CloudWatch
- 创建一个 Kinesis Stream (指定 Shard 数目)
- 创建一个 S3 Bucket
- 部署 Lambda (要指定能访问 S3 Bucket 的 Role, 并其他参数,如环境变量)
- 设置 Lambda 的 Kinesis 触发器 (指定源 Kinesis Stream 和 batchSize)
以下是 Lambda 的实现代码,从 Kinesis 读出字符串,逗号分割,第一部分作为 S3 Key, 第二部分作为文件内容写入到 S3 Bucket 中去。S3 Bucket 名称从环境变量中读取。
1public class Handler implements RequestHandler<KinesisEvent, String> {
2
3 @Override
4 public String handleRequest(KinesisEvent event, Context context) {
5 LambdaLogger logger = context.getLogger();
6 event.getRecords().forEach(record -> {
7 String data = new String(record.getKinesis().getData().array());
8 logger.log("Received data: " + data);
9
10 String[] keyAndContent = data.split(",");
11 ObjectMetadata objectMetadata = new ObjectMetadata();
12 objectMetadata.setContentLength(keyAndContent[1].getBytes().length);
13 AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();
14 s3Client.putObject(System.getenv("BUCKET_NAME"), keyAndContent[0],
15 new ByteArrayInputStream(keyAndContent[1].getBytes()), objectMetadata);
16 });
17 return null;
18 }
19}接下来的事情全部要交给 Terraform 来完成了,在于怎么写那个 tf 文件,为方便起见我们直接在这个 Java 项目根目录下创建一个
main.tf 文件。 1provider "aws" {
2 region = "us-east-1"
3 shared_credentials_file = "/Users/Yanbin/.aws/credentials" //默认就是 ~/.aws/credentials
4 profile = "yanbin" //默认是 default
5}
6
7resource "aws_s3_bucket" "test-bucket" {
8 bucket = "yanbin-test-bucket"
9 acl = "private"
10
11 tags {
12 Environment = "test"
13 }
14}
15
16//resource 后第二个字符串 name "test-stream" 还是很有用的,后面引用就靠它
17resource "aws_kinesis_stream" "test-stream" {
18 name = "yanbin-test-stream"
19 shard_count = 2
20
21 tags {
22 Environment = "test"
23 }
24}
25
26resource "aws_iam_role" "role_for_lambda" {
27 name = "yanbin_lambda_role"
28
29 //特别要注意这里的格式 <<EOF 是一整体,其中的 JSON 在下行一定要顶格写
30 assume_role_policy = <<EOF
31{
32 "Version": "2012-10-17",
33 "Statement": [
34 {
35 "Action": "sts:AssumeRole",
36 "Principal": {
37 "Service": "lambda.amazonaws.com"
38 },
39 "Effect": "Allow",
40 "Sid": ""
41 }
42 ]
43}
44EOF
45}
46
47resource "aws_iam_role_policy_attachment" "s3-access-policy-attachment" {
48 role = "${aws_iam_role.role_for_lambda.name}"
49 policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
50}
51
52resource "aws_iam_role_policy_attachment" "kinesis-access-policy-attachment" {
53 role = "${aws_iam_role.role_for_lambda.name}"
54 policy_arn = "arn:aws:iam::aws:policy/AmazonKinesisFullAccess"
55}
56
57resource "aws_iam_role_policy_attachment" "cloudWatch-access-policy-attachment" {
58 role = "${aws_iam_role.role_for_lambda.name}"
59 policy_arn = "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
60}
61
62resource "aws_lambda_function" "yanbin-test-lambda" {
63 filename = "target/hello-1.0.jar"
64 function_name = "yanbin-test-lambda"
65 role = "${aws_iam_role.role_for_lambda.arn}"
66 handler = "cc.unmi.Handler"
67 source_code_hash = "${base64sha256(file("target/hello-1.0.jar"))}"
68 runtime = "java8"
69 timeout = 300
70 memory_size = 512
71 description = "Test Lambda created by Terraform"
72
73 environment {
74 variables = {
75 BUCKET_NAME = "yanbin-test-bucket"
76 }
77 }
78}
79
80resource "aws_lambda_event_source_mapping" "kinesis_trigger" {
81 batch_size = 3
82 event_source_arn = "${aws_kinesis_stream.test-stream.arn}"
83 enabled = true
84 function_name = "${aws_lambda_function.yanbin-test-lambda.arn}"
85 starting_position = "LATEST"
86}由于贴代码有些问题,所以直接截的图。
main.tf 文件创建好,照例要在当前目录中运行 terraform init 先初始,而后才能执行 terraform plan|apply 等命令。编写好的 mail.tf 文件可以用 terraform fmt 帮我们格式化,在运行 terraform apply 之前最好运行一下 terraform plan, 好知道将要发生什么事。terraform apply 执行上面的配置,Terraform 将会做以下事情- 创建 Bucket
yanbin-test-bucket, 访问规则是 private, 设定 TagEnvironment = "test" - 创建 Kinesis Stream
yanbin-test-stream, Shard 数目是 2,设定 TagEnvironment = "test" - 创建 IAM Role
yanbin-lambda_role, 并赋予 S3, Kinesis, CloudWatch 的完全访问权限 - 上传程序包部署 Lambda
yanbin-test-lambda, 并设置 role 为上一步创建的 role, 设置其他属性,及环境变量BUCKET. 以后运行terraform plan只有发现hello-1.0.jar包的哈稀值变了才会更新 Lambda 程序包 - 为上面的 Lambda 创建一个 Kinesis Trigger, batchSize 为 3, 监听第 2 步创建的 Kinesis Stream
现在一切准备就绪,可以登陆到 AWS 的控制台看下 Terraform 是不是为我们创建好了应有的东西。一切正常的就可以发送 Kinesis 消息到我们新创建的 Kinesis Stream 了,看看在 Bucket 里是不是有了 Lambda 生成的文件。
上面创建的东西不想要了,想统统干掉,那就更简单了
terraform destroy 就行了,简值是键删除。
永久链接 https://yanbin.blog/terraform-deploy-lambda-create-resources/, 来自 隔叶黄莺 Yanbin's Blog[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。