Skip to content

Commit c45ceab

Browse files
lycbrianxshot9011
andauthored
feat: support var (#15)
* feat:suport env var * feat:suport env var * (fix): typo * (fix): typo in examples * feat:support env in lambda * chore: scan via central workflow for public module * (update): remove zip file Co-authored-by: sedthawut tipkanpirome <40098197+xshot9011@users.noreply.github.com>
1 parent b52e870 commit c45ceab

File tree

13 files changed

+419
-93
lines changed

13 files changed

+419
-93
lines changed

.github/workflows/code-scan.yml

Lines changed: 0 additions & 21 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
All notable changes to this module will be documented in this file.
44

5+
## [v1.1.4] - 2022-12-15
6+
7+
### Added
8+
- var `environment_variables`
9+
- add dynamic `environment` in resource `aws_lambda_function.this`
10+
- add access_key_rotate example
11+
12+
### Changed
13+
14+
- fix typo, change from `pricipal` to `principal` in resource `aws_lambda_permission.allow_serivce`
15+
516
## [v1.1.3] - 2022-11-23
617

718
### Added

README.md

Lines changed: 66 additions & 65 deletions
Large diffs are not rendered by default.

examples/access_key_rotate/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!-- BEGIN_TF_DOCS -->
2+
## Requirements
3+
4+
| Name | Version |
5+
|---------------------------------------------------------------------------|----------|
6+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.0 |
7+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.0.0 |
8+
9+
## Providers
10+
11+
No providers.
12+
13+
## Modules
14+
15+
| Name | Source | Version |
16+
|--------------------------------------------------------|--------|---------|
17+
| <a name="module_lambda"></a> [lambda](#module\_lambda) | ../../ | n/a |
18+
19+
## Resources
20+
21+
No resources.
22+
23+
## Inputs
24+
25+
| Name | Description | Type | Default | Required |
26+
|-----------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|------------|---------|:--------:|
27+
| <a name="input_custom_tags"></a> [custom\_tags](#input\_custom\_tags) | Custom tags which can be passed on to the AWS resources. They should be key value pairs having distinct keys | `map(any)` | `{}` | no |
28+
| <a name="input_environment"></a> [environment](#input\_environment) | Environment Variable used as a prefix | `string` | n/a | yes |
29+
| <a name="input_name"></a> [name](#input\_name) | Name of the ECS cluster and s3 also redis to create | `string` | n/a | yes |
30+
| <a name="input_prefix"></a> [prefix](#input\_prefix) | The prefix name of customer to be displayed in AWS console and resource | `string` | n/a | yes |
31+
32+
## Outputs
33+
34+
No outputs.
35+
<!-- END_TF_DOCS -->

examples/access_key_rotate/main.tf

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
locals {
2+
name = format("%s-%s-%s", "oozou", "test", "app")
3+
}
4+
5+
data "aws_caller_identity" "this" {}
6+
data "aws_region" "this" {}
7+
8+
/* -------------------------------------------------------------------------- */
9+
/* SNS Notification */
10+
/* -------------------------------------------------------------------------- */
11+
data "aws_iam_policy_document" "lambda_access_kms_policy" {
12+
statement {
13+
sid = "AllowLambdaToPublishMessageToEncryptedSNS"
14+
effect = "Allow"
15+
actions = [
16+
"kms:Decrypt",
17+
"kms:GenerateDataKey*",
18+
]
19+
resources = ["*"]
20+
principals {
21+
identifiers = ["cloudwatch.amazonaws.com", "events.amazonaws.com"]
22+
type = "Service"
23+
}
24+
}
25+
}
26+
27+
# TODO fix KMS naming in SNS module
28+
module "sns" {
29+
source = "oozou/sns/aws"
30+
version = "1.0.1"
31+
32+
prefix = "oozou"
33+
environment = "test"
34+
name = format("%s-accesskey-rotate", "app")
35+
display_name = "Alerting Center"
36+
37+
sns_permission_configuration = {
38+
allow_cloudwatch_to_publish_alert = {
39+
pricipal = "cloudwatch.amazonaws.com"
40+
}
41+
allow_eventbridge_to_publish_alert = {
42+
pricipal = "events.amazonaws.com"
43+
}
44+
}
45+
46+
subscription_configurations = {
47+
oozou_admin = {
48+
protocol = "email"
49+
addresses = ["xxx@xxx.com"]
50+
# filter_policy = jsonencode(var.admin_filter_polciy)
51+
}
52+
}
53+
54+
additional_kms_key_policies = [data.aws_iam_policy_document.lambda_access_kms_policy.json]
55+
56+
tags = {}
57+
}
58+
59+
/* -------------------------------------------------------------------------- */
60+
/* Lambda */
61+
/* -------------------------------------------------------------------------- */
62+
63+
resource "aws_iam_policy" "sns_publish_policy" {
64+
name = format("%s-sns-publish-access", local.name)
65+
path = "/"
66+
67+
policy = jsonencode({
68+
Version = "2012-10-17"
69+
Statement = [
70+
{
71+
Action = [
72+
"sns:Publish",
73+
]
74+
Effect = "Allow"
75+
"Resource": module.sns.sns_topic_arn
76+
},
77+
]
78+
})
79+
}
80+
81+
resource "aws_iam_policy" "iam_updateKey_policy" {
82+
name = format("%s-iam-updatekey-access", local.name)
83+
path = "/"
84+
85+
policy = jsonencode({
86+
Version = "2012-10-17"
87+
Statement = [
88+
{
89+
Action = [
90+
"iam:CreateAccessKey",
91+
"iam:UpdateAccessKey",
92+
"iam:ListAccessKeys",
93+
"iam:DeleteAccessKey",
94+
]
95+
Effect = "Allow"
96+
"Resource": aws_iam_user.s3_presigned_user.arn
97+
},
98+
]
99+
})
100+
}
101+
102+
resource "aws_iam_policy" "secretsmanager_updatesecret_policy" {
103+
name = format("%s-secretsmanager-updatesecret-access", local.name)
104+
path = "/"
105+
106+
policy = jsonencode({
107+
Version = "2012-10-17"
108+
Statement = [
109+
{
110+
Action = [
111+
"secretsmanager:GetSecretValue",
112+
"secretsmanager:PutSecretValue"
113+
]
114+
Effect = "Allow"
115+
"Resource": aws_secretsmanager_secret.accesskey.arn
116+
},
117+
]
118+
})
119+
}
120+
121+
module "lambda_accesskey_rotate" {
122+
source = "../.."
123+
124+
prefix = "oozou"
125+
environment = "test"
126+
name = "accesskey_rotate"
127+
128+
is_edge = false
129+
130+
# Source code
131+
source_code_dir = "./src"
132+
file_globs = ["access_key_rotate.py"]
133+
compressed_local_file_dir = "./outputs"
134+
135+
# Lambda Env
136+
runtime = "python3.9"
137+
handler = "access_key_rotate.handler"
138+
environment_variables = {
139+
iam_username = aws_iam_user.s3_presigned_user.name
140+
secret_name = aws_secretsmanager_secret.accesskey.name
141+
sns_topic_arn = module.sns.sns_topic_arn
142+
}
143+
144+
# IAM
145+
additional_lambda_role_policy_arns = [
146+
aws_iam_policy.sns_publish_policy.arn,
147+
aws_iam_policy.secretsmanager_updatesecret_policy.arn,
148+
aws_iam_policy.iam_updateKey_policy.arn
149+
]
150+
151+
# Resource policy
152+
lambda_permission_configurations = {
153+
allow_trigger_from_eventbridge = {
154+
principal = "secretsmanager.amazonaws.com"
155+
}
156+
}
157+
158+
159+
tags = {}
160+
}
161+
162+
/* -------------------------------------------------------------------------- */
163+
/* Secret */
164+
/* -------------------------------------------------------------------------- */
165+
166+
module "secret_kms_key" {
167+
source = "oozou/kms-key/aws"
168+
version = "1.0.0"
169+
170+
name = format("%s-service-secrets", "app")
171+
prefix = "oozou"
172+
environment = "test"
173+
key_type = "service"
174+
append_random_suffix = true
175+
description = format("Secure Secrets Manager's service secrets for service %s", "app")
176+
177+
service_key_info = {
178+
aws_service_names = tolist([format("secretsmanager.%s.amazonaws.com", data.aws_region.this.name)])
179+
caller_account_ids = tolist([data.aws_caller_identity.this.account_id])
180+
}
181+
182+
tags = merge({}, { "Name" : format("%s-service-secrets", "app") })
183+
}
184+
185+
resource "aws_secretsmanager_secret" "accesskey" {
186+
name = format("%s/accesskey", local.name)
187+
description = "access key secret with rotation"
188+
kms_key_id = module.secret_kms_key.key_arn
189+
recovery_window_in_days = 0
190+
191+
}
192+
193+
resource "aws_secretsmanager_secret_rotation" "accesskey" {
194+
secret_id = aws_secretsmanager_secret.accesskey.id
195+
rotation_lambda_arn = module.lambda_accesskey_rotate.function_arn
196+
rotation_rules {
197+
automatically_after_days = 7
198+
}
199+
depends_on = [
200+
module.lambda_accesskey_rotate
201+
]
202+
}
203+
204+
/* -------------------------------------------------------------------------- */
205+
/* IAM User */
206+
/* -------------------------------------------------------------------------- */
207+
208+
209+
resource "aws_iam_user" "s3_presigned_user" {
210+
name = "s3_presigned_user"
211+
path = "/"
212+
213+
tags = merge({}, { "Name" = "s3_presigned_user" })
214+
}
215+

examples/access_key_rotate/outputs.tf

Whitespace-only changes.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import json
2+
import boto3
3+
import base64
4+
import datetime
5+
import os
6+
from datetime import date
7+
from botocore.exceptions import ClientError
8+
iam = boto3.client('iam')
9+
secretmanager = boto3.client('secretsmanager')
10+
IAM_UserName = os.environ['iam_username']
11+
secret_name = os.environ['secret_name']
12+
TopicArn = os.environ['sns_topic_arn']
13+
sns_send_report = boto3.client('sns',region_name='ap-southeast-1')
14+
15+
def error_handling(message):
16+
sns_send_report.publish(TopicArn=TopicArn,
17+
Subject="Access key rotate failed",
18+
Message="Access key rotate failed: "+str(message) )
19+
raise
20+
21+
def check_key():
22+
try:
23+
response = iam.list_access_keys(UserName=IAM_UserName)
24+
print(response)
25+
if(len(response['AccessKeyMetadata']) >1):
26+
raise Exception("more than 1 access key found")
27+
elif(len(response['AccessKeyMetadata']) ==0):
28+
raise Exception("no access key found")
29+
return(response['AccessKeyMetadata'][0])
30+
except ClientError as e:
31+
error_handling(e)
32+
except Exception as e:
33+
error_handling(e)
34+
35+
def create_key():
36+
try:
37+
response = iam.create_access_key(UserName=IAM_UserName)
38+
accessKeyID = response['AccessKey']['AccessKeyId']
39+
accessKeySecret = response['AccessKey']['SecretAccessKey']
40+
json_data=json.dumps({'accessKeyID':accessKeyID,'accessKeySecret':accessKeySecret})
41+
secmanagerv=secretmanager.put_secret_value(SecretId=secret_name,SecretString=json_data)
42+
except ClientError as e:
43+
error_handling(e)
44+
45+
def delete_key(accessKeyMetadata):
46+
try:
47+
userName = accessKeyMetadata['UserName']
48+
accessKeyId = accessKeyMetadata['AccessKeyId']
49+
iam.update_access_key(AccessKeyId=accessKeyId,Status='Inactive',UserName=userName)
50+
iam.delete_access_key (UserName=userName,AccessKeyId=accessKeyId)
51+
except ClientError as e:
52+
error_handling(e)
53+
54+
def handler(event, context):
55+
# get the existing key
56+
accessKeyMetadata = check_key()
57+
58+
# create new accesskey and update key in secret manager
59+
create_key()
60+
61+
# delete the old key
62+
delete_key(accessKeyMetadata)

examples/access_key_rotate/variables.tf

Whitespace-only changes.

examples/access_key_rotate/version.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">= 1.0.0"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 4.0.0"
8+
}
9+
}
10+
}

examples/complete/main.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ module "lambda" {
4141
# Resource policy
4242
lambda_permission_configurations = {
4343
lambda_on_my_account = {
44-
pricipal = "apigateway.amazonaws.com"
44+
principal = "apigateway.amazonaws.com"
4545
source_arn = "arn:aws:execute-api:ap-southeast-1:557291035112:lk36vflbha/*/*/"
4646
}
4747
lambda_on_my_another_account_wrong = {
48-
pricipal = "apigateway.amazonaws.com"
48+
principal = "apigateway.amazonaws.com"
4949
source_arn = "arn:aws:execute-api:ap-southeast-1:224563527112:q6pwa6wgr6/*/*/"
5050
source_account = "557291035112"
5151
}
5252
lambda_on_my_another_account_correct = {
53-
pricipal = "apigateway.amazonaws.com"
53+
principal = "apigateway.amazonaws.com"
5454
source_arn = "arn:aws:execute-api:ap-southeast-1:557291035112:wpj4t3scmb/*/*/"
5555
}
5656
}

0 commit comments

Comments
 (0)