Skip to content

Commit 3cdb042

Browse files
authored
Merge pull request #1 from rhythmictech/demo
initial commit
2 parents eab94b5 + c2778bd commit 3cdb042

12 files changed

Lines changed: 396 additions & 0 deletions
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
name: pre-commit-check
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
9+
jobs:
10+
build:
11+
runs-on: macOS-latest
12+
steps:
13+
- uses: actions/checkout@v1
14+
15+
- name: Install prerequisites
16+
run: |
17+
brew install tfenv tflint terraform-docs pre-commit
18+
pre-commit install
19+
tfenv install
20+
- name: pre-commit run all
21+
run: |
22+
pre-commit run -a

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Local .terraform directories
2+
**/.terraform/*
3+
4+
# .tfstate files
5+
*.tfstate
6+
*.tfstate.*
7+
8+
# .tfvars files
9+
*.tfvars

.pre-commit-config.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
repos:
2+
- repo: git://github.com/antonbabenko/pre-commit-terraform
3+
rev: v1.24.0
4+
hooks:
5+
- id: terraform_fmt
6+
- id: terraform_docs
7+
- repo: https://github.com/pre-commit/pre-commit-hooks
8+
rev: v2.4.0
9+
hooks:
10+
- id: end-of-file-fixer
11+
- id: trailing-whitespace
12+
- id: no-commit-to-branch

.terraform-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.12.25

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Rhythmic Technologies, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

bin/install-macos.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash
2+
3+
echo 'installing brew packages'
4+
brew install tfenv tflint terraform-docs pre-commit
5+
6+
echo 'installing pre-commit hooks'
7+
pre-commit install
8+
9+
echo 'installing terraform with tfenv'
10+
tfenv install

create_jira.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import boto3
2+
import json
3+
from botocore.vendored import requests
4+
5+
def add_priority(issue, priority):
6+
fields = issue["fields"]
7+
fields["priority"] = {"name": priority}
8+
9+
def add_assignee(issue, assignee):
10+
fields = issue["fields"]
11+
fields["assignee"] = {"name": assignee}
12+
13+
def add_due_date(issue, due_date):
14+
fields = issue["fields"]
15+
fields["duedate"] = due_date
16+
17+
def handler(event, context):
18+
19+
client = boto3.client("ssm")
20+
21+
ssm_parameter_name = event["SSMParameterName"].strip()
22+
secret = client.get_parameter(Name=ssm_parameter_name, WithDecryption=True)['Parameter']['Value']
23+
24+
username = event["JiraUsername"].strip()
25+
url = event["JiraURL"].strip()
26+
27+
issue = {
28+
"fields": {
29+
"summary": event["IssueSummary"].strip(),
30+
"project": {
31+
"key": event["ProjectKey"].strip()
32+
},
33+
"description": event["IssueDescription"].strip(),
34+
"issuetype": {
35+
"name": event["IssueTypeName"].strip()
36+
}
37+
}
38+
}
39+
40+
priority = event["PriorityName"].strip()
41+
if priority:
42+
add_priority(issue, priority)
43+
44+
assignee = event["AssigneeName"].strip()
45+
46+
if assignee:
47+
add_assignee(issue, assignee)
48+
49+
due_date = event["DueDate"].strip()
50+
if due_date:
51+
add_due_date(issue, due_date)
52+
53+
data = json.dumps(issue)
54+
55+
headers = {'Content-Type':'application/json'}
56+
57+
response = requests.post('{0}/rest/api/2/issue/'.format(url),
58+
headers=headers,
59+
data=data,
60+
auth=(username, secret))
61+
62+
if not response.ok:
63+
raise Exception("Received error with status code " + str(response.status_code) + " from Jira")
64+
else:
65+
issue_key = (response.json()["key"])
66+
return {"IssueKey" : issue_key}

jira.tf

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
locals {
2+
jira_name = "${var.name}-create-jira"
3+
}
4+
5+
resource "aws_sns_topic_subscription" "jira" {
6+
count = var.enable_jira_integration ? 1 : 0
7+
endpoint = aws_lambda_function.jira[0].arn
8+
endpoint_auto_confirms = true
9+
protocol = "https"
10+
topic_arn = aws_sns_topic.ticket.arn
11+
}
12+
13+
data "archive_file" "jira" {
14+
type = "zip"
15+
source_file = "${path.module}/create_jira.py"
16+
output_path = "${path.module}/tmp/create_jira.zip"
17+
}
18+
19+
data "aws_iam_policy_document" "jira_assume" {
20+
statement {
21+
actions = [
22+
"sts:AssumeRole",
23+
]
24+
25+
principals {
26+
type = "Service"
27+
identifiers = ["lambda.amazonaws.com"]
28+
}
29+
}
30+
}
31+
32+
resource "aws_iam_role" "jira" {
33+
count = var.enable_jira_integration ? 1 : 0
34+
name_prefix = local.jira_name
35+
assume_role_policy = data.aws_iam_policy_document.jira_assume.json
36+
}
37+
38+
resource "aws_iam_role_policy_attachment" "jira" {
39+
count = var.enable_jira_integration ? 1 : 0
40+
role = aws_iam_role.jira[0].name
41+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
42+
}
43+
44+
resource "aws_lambda_function" "jira" {
45+
count = var.enable_jira_integration ? 1 : 0
46+
function_name = local.jira_name
47+
filename = data.archive_file.jira.output_path
48+
handler = "create_jira.handler"
49+
role = aws_iam_role.jira[0].arn
50+
runtime = "python3.7"
51+
source_code_hash = data.archive_file.jira.output_base64sha256
52+
tags = var.tags
53+
timeout = 180
54+
55+
environment {
56+
variables = {
57+
58+
}
59+
}
60+
61+
lifecycle {
62+
ignore_changes = [
63+
filename,
64+
last_modified,
65+
]
66+
}
67+
}
68+
69+
resource "aws_lambda_permission" "jira" {
70+
count = var.enable_jira_integration ? 1 : 0
71+
statement_id_prefix = "AllowExecutionFromCloudWatch-"
72+
action = "lambda:InvokeFunction"
73+
function_name = aws_lambda_function.jira[0].function_name
74+
principal = "sns.amazonaws.com"
75+
source_arn = aws_sns_topic.ticket.arn
76+
77+
lifecycle {
78+
create_before_destroy = true
79+
}
80+
}

main.tf

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
data "aws_caller_identity" "current" {
2+
}
3+
4+
locals {
5+
account_id = data.aws_caller_identity.current.account_id
6+
alert_topic_name = "${var.name}-Alert-Topic"
7+
ticket_topic_name = "${var.name}-Ticket-Topic"
8+
notify_topic_name = "${var.name}-Notify-Topic"
9+
}
10+
11+
resource "aws_sns_topic" "alert" {
12+
name = local.alert_topic_name
13+
tags = var.tags
14+
}
15+
16+
resource "aws_sns_topic_subscription" "alert" {
17+
endpoint = var.alert_webhook
18+
endpoint_auto_confirms = true
19+
protocol = "https"
20+
topic_arn = aws_sns_topic.alert.arn
21+
}
22+
23+
resource "aws_sns_topic_policy" "alert" {
24+
arn = aws_sns_topic.notify.arn
25+
policy = data.aws_iam_policy_document.policy.json
26+
}
27+
28+
resource "aws_sns_topic" "ticket" {
29+
name = local.ticket_topic_name
30+
tags = var.tags
31+
}
32+
33+
resource "aws_sns_topic_policy" "ticket" {
34+
arn = aws_sns_topic.notify.arn
35+
policy = data.aws_iam_policy_document.policy.json
36+
}
37+
38+
resource "aws_sns_topic" "notify" {
39+
name = local.notify_topic_name
40+
tags = var.tags
41+
}
42+
43+
resource "aws_sns_topic_policy" "notify" {
44+
arn = aws_sns_topic.notify.arn
45+
policy = data.aws_iam_policy_document.policy.json
46+
}
47+
48+
data "aws_iam_policy_document" "policy" {
49+
50+
statement {
51+
effect = "Allow"
52+
sid = "AllowAWSToPublish"
53+
54+
actions = [
55+
"SNS:AddPermission",
56+
"SNS:GetTopicAttributes",
57+
"SNS:ListSubscriptionsByTopic",
58+
"SNS:Publish",
59+
"SNS:RemovePermission"
60+
]
61+
62+
condition {
63+
test = "StringEquals"
64+
variable = "AWS:SourceOwner"
65+
66+
values = [
67+
local.account_id
68+
]
69+
}
70+
71+
resources = ["*"]
72+
73+
principals {
74+
type = "AWS"
75+
identifiers = ["*"]
76+
}
77+
}
78+
79+
statement {
80+
effect = "Allow"
81+
sid = "CloudWatchEvents"
82+
83+
actions = [
84+
"sns:Publish"
85+
]
86+
87+
resources = ["*"]
88+
89+
principals {
90+
type = "Service"
91+
92+
identifiers = [
93+
"events.amazonaws.com"
94+
]
95+
}
96+
}
97+
}

outputs.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
output "sns_topic_alert_arn" {
2+
description = "Alert Topic ARN"
3+
value = aws_sns_topic.alert.arn
4+
}
5+
6+
output "sns_topic_notify_arn" {
7+
description = "Notification Topic ARN"
8+
value = aws_sns_topic.notify.arn
9+
}
10+
11+
output "sns_topic_ticket_arn" {
12+
description = "Ticketing Topic ARN"
13+
value = aws_sns_topic.ticket.arn
14+
}

0 commit comments

Comments
 (0)