Skip to content

Commit

Permalink
Proton sample services
Browse files Browse the repository at this point in the history
  • Loading branch information
syedsaadahmed1 committed May 6, 2022
1 parent dbaf836 commit 7df5b24
Show file tree
Hide file tree
Showing 29 changed files with 412 additions and 6 deletions.
44 changes: 40 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,48 @@
## AWS Proton Sample Fargate Service
# AWS Proton Sample Services

This sample contains a simple Dockerfile and static website that can be deployed with AWS Proton using the [Loadbalanced Fargate Service](https://github.com/aws-samples/aws-proton-sample-templates/tree/main/loadbalanced-fargate-svc) service template.
This repository contains samples of application code that can be deployed with AWS Proton using the [AWS Proton Sample Services](https://github.com/aws-samples/aws-proton-sample-templates/tree/main/service-templates).

- ## ecs-backend

Flask app that responds with a Hello message along with the Time. [README](./ecs-backend)

- ## ecs-ping-backend-a-record

Application code to ping Fargate backend service using service discovery. [README](./ecs-ping-backend-a-record)

- ## ecs-ping-backend-srv-record

Application code to ping ECS on EC2 backend service using service discovery. [README](./ecs-ping-backend-srv-record)

- ## ecs-ping-sns

Python application that sends a random 5-letter string along with the time to the shared SNS topic, every 5 minutes. [README](./ecs-ping-sns)

- ## ecs-static-website

Containerized static website. [README](./ecs-static-website)

- ## ecs-worker

Python application that polls the SQS queue for messages, and writes the message body to CloudWatch logs. [README](./ecs-worker)

- ## lambda-ping-sns

Lambda function to send a random string and time to the shared SNS topic, whenever invoked by API Gateway HTTP API. [README](./lambda-ping-sns)

- ## lambda-worker

Lambda function that writes the event, context object and SQS message to CloudWatch Logs. [README](./lambda-worker)

## Security

See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
See [CONTRIBUTING](./CONTRIBUTING.md#security-issue-notifications) for more information.

## Code of Conduct

See [CODE OF CONDUCT](./CODE_OF_CONDUCT.md) for more information.

## License

This library is licensed under the MIT-0 License. See the LICENSE file.
This library is licensed under the MIT-0 License. See the [LICENSE](./LICENSE) file.

5 changes: 5 additions & 0 deletions ecs-backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM python:3.8.3-slim-buster
COPY app.py requirements.txt ./
RUN pip install -r requirements.txt
EXPOSE 80
CMD [ "python", "app.py"]
3 changes: 3 additions & 0 deletions ecs-backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Expected output

{"response": "Hello from backend-svc. Time: Monday, May 02 2022, 15:26:06"}
25 changes: 25 additions & 0 deletions ecs-backend/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from flask import Flask
import json
import time

app = Flask(__name__)


@app.route('/ping', methods=['GET'])
def healthcheck():
return "ok"


@app.route('/', methods=['GET'])
def inc():
data = {"response": "Hello from backend-svc. Time: {}".format(time.strftime('%A, %B %d %Y, %H:%M:%S'))}
response = app.response_class(
response=json.dumps(data),
status=200,
mimetype='application/json'
)
return response


if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
1 change: 1 addition & 0 deletions ecs-backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
flask
5 changes: 5 additions & 0 deletions ecs-ping-backend-a-record/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM python:3.8.3-slim-buster
COPY app.py requirements.txt ./
RUN pip install -r requirements.txt
EXPOSE 80
CMD [ "python", "app.py"]
3 changes: 3 additions & 0 deletions ecs-ping-backend-a-record/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Expected output

{"backend_response": "Hello from backend-svc. Time: Monday, May 02 2022, 15:26:06"}
29 changes: 29 additions & 0 deletions ecs-ping-backend-a-record/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from flask import Flask
import os
import urllib.request
import json

app = Flask(__name__)
BACKEND_URL = "http://{}".format(os.getenv("BACKEND_URL"))


@app.route('/ping', methods=['GET'])
def healthcheck():
return "ok"


@app.route('/', methods=['GET'])
def inc():
data = {}
backend_response = json.loads(urllib.request.urlopen(BACKEND_URL).read())
data['backend_response'] = backend_response['response']
response = app.response_class(
response=json.dumps(data),
status=200,
mimetype='application/json'
)
return response


if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
1 change: 1 addition & 0 deletions ecs-ping-backend-a-record/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
flask
5 changes: 5 additions & 0 deletions ecs-ping-backend-srv-record/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM python:3.8.3-slim-buster
COPY app.py requirements.txt ./
RUN pip install -r requirements.txt
EXPOSE 80
CMD [ "python", "app.py"]
3 changes: 3 additions & 0 deletions ecs-ping-backend-srv-record/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Expected output

{"backend_response": "Hello from backend-svc. Time: Monday, May 02 2022, 15:26:06"}
38 changes: 38 additions & 0 deletions ecs-ping-backend-srv-record/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from flask import Flask
import os
import urllib.request
import json
import dns.resolver


app = Flask(__name__)
BACKEND_RECORD = str(os.getenv("BACKEND_RECORD"))

@app.route('/ping', methods=['GET'])
def healthcheck():
return "ok"


@app.route('/', methods=['GET'])
def inc():
data = {}
answers = dns.resolver.query(BACKEND_RECORD, 'SRV')
domain = ''
port = ''
for rdata in answers:
domain = rdata.target
port = rdata.port

BACKEND_URL = "http://"+str(domain)+":"+str(port)
backend_response = json.loads(urllib.request.urlopen(BACKEND_URL).read())
data['backend_response'] = backend_response['response']
response = app.response_class(
response=json.dumps(data),
status=200,
mimetype='application/json'
)
return response


if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
2 changes: 2 additions & 0 deletions ecs-ping-backend-srv-record/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
flask
dnspython
7 changes: 7 additions & 0 deletions ecs-ping-sns/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM python:3.8-alpine
WORKDIR /app
COPY requirements.txt /requirements.txt
RUN pip install -r /requirements.txt
COPY . /app
EXPOSE 80
CMD ["python3", "app.py"]
3 changes: 3 additions & 0 deletions ecs-ping-sns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Expected output

{"Hello! Message srptt sent at time Monday, May 02 2022, 15:34:19"}
29 changes: 29 additions & 0 deletions ecs-ping-sns/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import logging
import os
import json
import random, string
import time
import boto3

TOPIC_ARNS = json.loads(os.getenv("SNS_TOPIC_ARN"))
client = boto3.client('sns', region_name = os.getenv("SNS_REGION"))
logger = logging.getLogger()
logging.basicConfig(level=logging.INFO,
format='%(asctime)s: %(levelname)s: %(message)s')

def generate_random(char_length):
characters = string.ascii_lowercase
return ''.join(random.choice(characters) for i in range(char_length))

def send_message():
ping_message = "Hello! Message {} sent at time {}".format(generate_random(5),time.strftime('%A, %B %d %Y, %H:%M:%S'))
response = client.publish(
TopicArn=TOPIC_ARNS["ping"],
Message=ping_message
)
message_id = response['MessageId']
logger.info("Published message: %s.", message_id)
return message_id

if __name__ == '__main__':
send_message()
1 change: 1 addition & 0 deletions ecs-ping-sns/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
boto3
File renamed without changes.
3 changes: 3 additions & 0 deletions ecs-static-website/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Expected output

![image](./image.png)
Binary file added ecs-static-website/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions index.html → ecs-static-website/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<g id="Group" transform="translate(18.277778, 147.092593)" fill="#232F3E" font-family="Helvetica-Bold, Helvetica" font-size="17.4074074" font-weight="bold">
<g id="AWS-Proton">
<text>
<tspan x="0" y="16"> Testing</tspan>
<tspan x="0" y="16">AWS Proton</tspan>
</text>
</g>
</g>
Expand All @@ -32,4 +32,4 @@
</svg>
</div>
</body>
</html>
</html>
6 changes: 6 additions & 0 deletions ecs-worker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM python:3.8-alpine
WORKDIR /app
COPY requirements.txt /requirements.txt
RUN pip install -r /requirements.txt
COPY . /app
CMD ["python3", "app.py"]
17 changes: 17 additions & 0 deletions ecs-worker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Expected output

INFO: The message body: {
"Type" : "Notification",
"MessageId" : "605944d3-5636-5e1c-8a77-1e3aaa0dc93b",
"TopicArn" : "arn:aws:sns:us-east-2:XXXXXXXXXXXX:AWSProton-fargate-env-pro-cloudformation--MPDTYJAPBFYGPYF-ping",
"Message" : "Hello! Message srptt sent at time Monday, May 02 2022, 15:34:19",
"Timestamp" : "2022-05-02T15:34:19.387Z",
"SignatureVersion" : "1",
"Signature" : "WNHwbHUbTdc7yvJEmY1S9cvGUE0JMuP/PR6GNYe1p7bnyYGcJ7wB3QU3W/5264/VkPN+eMm+FOkW/PZAQr36Tww8TwPMr21xoSZyXfYoyvyk1FecS2i3IMmgRrYBQAi9BbBIhZO+2zBD35640rKAPakvPbNjhV+SNfeF3cPBezlSAgREUd+TovsmI+78h8AIa+dmUaZHFKCFCFmhOo+ovLZGQoLw+H4ow/YofFyzZCr/jNx4iHiI7K15YQ6TPky0S+4xpxMhjJD6vQ2XR75cnZpjKgQ6ip+uTXC4eKYE6mRHW/JBeriwKMv6TaQ3UatiJheyFJ28WRQxAZWeOW1k4g==",
"SigningCertURL" : "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-7ff5318490ec183fbaddaa2a969abfda.pem",
"UnsubscribeURL" : "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:XXXXXXXXXXXX:AWSProton-fargate-env-pro-cloudformation--MPDTYJAPBFYGPYF-ping:445f255f-c616-4852-aa76-b30a40864848"
}

INFO: Deleting message from the queue...

INFO: Received and deleted message(s) from https://sqs.us-east-2.amazonaws.com/XXXXXXXXXXXX/AWSProton-worker-fargate-worker-fargate-c-ServiceEcsProcessingQueue-XWL8D7ptF4mP with message
51 changes: 51 additions & 0 deletions ecs-worker/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import logging
import boto3
import os
from botocore.exceptions import ClientError
import json

QUEUE_URI = os.getenv("QUEUE_URI")
logger = logging.getLogger()
logging.basicConfig(level=logging.INFO,
format='%(asctime)s: %(levelname)s: %(message)s')

sqs_client = boto3.client("sqs", region_name = os.getenv("QUEUE_REGION"))


def receive_queue_message():
try:
response = sqs_client.receive_message(QueueUrl=QUEUE_URI, WaitTimeSeconds=5, MaxNumberOfMessages=1)
except ClientError:
logger.exception('Could not receive the message from the - {}.'.format(
QUEUE_URI))
raise
else:
return response


def delete_queue_message(receipt_handle):
try:
response = sqs_client.delete_message(QueueUrl=QUEUE_URI,
ReceiptHandle=receipt_handle)
except ClientError:
logger.exception('Could not delete the meessage from the - {}.'.format(
QUEUE_URI))
raise
else:
return response


if __name__ == '__main__':
while True:
messages = receive_queue_message()
print(messages)

if "Messages" in messages:
for msg in messages['Messages']:
msg_body = msg['Body']
receipt_handle = msg['ReceiptHandle']
logger.info(f'The message body: {msg_body}')
logger.info('Deleting message from the queue...')
resp_delete = delete_queue_message(receipt_handle)
logger.info(
'Received and deleted message(s) from {} with message {}.'.format(QUEUE_URI,resp_delete))
1 change: 1 addition & 0 deletions ecs-worker/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
boto3
7 changes: 7 additions & 0 deletions lambda-ping-sns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Expected output

{
"functionName": "apigw-lambda-svc-prod-function",
"SNS_Message": "Message a9rv97lkvh sent at Sun May 01 2022 18:09:43 GMT+0000 (Coordinated Universal Time)",
"SNS_Subject": "New message from publisher"
}
49 changes: 49 additions & 0 deletions lambda-ping-sns/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: MIT-0
*/

// 1. Receive event from API Gateway HTTP API.
// 2. Log event and context object to CloudWatch Logs.
// 3. Send SNS message and log results to CloudWatch Logs.
// 3. Return a response with event information and SNS message to the caller.

const AWS = require('aws-sdk')
AWS.config.region = process.env.AWS_REGION
const sns = new AWS.SNS({apiVersion: '2012-11-05'})

exports.handler = async (event, context) => {
try {
// Log event and context object to CloudWatch Logs
console.log("Event: ", JSON.stringify(event, null, 2));
console.log("Context: ", JSON.stringify(context, null, 2));
sns_message = (Math.random()+1).toString(36).slice(2);
date = Date();

// Create event object to return to caller
const eventObj = {
functionName: context.functionName,
SNS_Message: `Message ${sns_message} sent at ${date}`,
SNS_Subject: 'New message from publisher',
};

// Params object for SNS
const params = {
Message: `Message ${sns_message} sent at ${date}`,
Subject: 'New message from publisher',
TopicArn: process.env.SNSTopicArn
};

// Send to SNS
const result = await sns.publish(params).promise();
console.log(result);

const response = {
statusCode: 200,
body: JSON.stringify(eventObj, null, 2),
};
return response;
} catch (error) {
console.error(error);
throw new Error(error);
}
};
Loading

0 comments on commit 7df5b24

Please sign in to comment.