Hello Techies,
I recently worked on one project where I was using AWS on codepipeline. In our project, we need to provide Code Pipeline status back to the application team immediately. So that team can take quick action on that and speed up deployment/delivery. Based on this requirement, we have decided to implement Microsoft Team Notification where your AWS Code Pipeline state will be sent to the Microsoft Teams channel. This article will help you to implement AWS CodePipleline notification with Microsoft Teams Webhook Channel.
Ref – How to configure incoming webhook on Microsoft Team channel
How does it work?
The main role played by Cloudwatch Events Rule. It is checking the Code Pipeline Execution State Change and When the pipeline state is FAILED/SUCCEEDED it sends the event to SNS and Amazon SNS triggers the lambda function with a message to the Microsoft Teams channel.
Prerequisites
- AWS-CLI to deploy AWS Cloud Formation Stack
- Incoming Webhook URL for your Microsoft Teams Channel
- Working AWS Code Pipeline
- At least basic experience with AWS Cloud Formation
- Basic syntax knowledge of Python
Cloud Formation Code
AWSTemplateFormatVersion: '2010-09-09'
Description: Caz Creek IAM Roles - 1.6.0
Parameters:
TeamsURL:
Description: "Incoming Microsoft Teams Webhook URL"
Type: String
Default: "<MS TEAM WEB HOOK URL>"
# ToDo Add your Incoming Webhood URL
CodePipelineName:
Description: "Codepipeline Name"
Type: String
Default: "<CODE PIPELINE NAME>"
#TODO Add your parameter
Resources:
NotificationLambdaFunction:
Type: 'AWS::Lambda::Function'
Properties:
Handler: index.index_handler
Code:
ZipFile: |
import urllib3
import json
import os
http = urllib3.PoolManager()
def index_handler(event, context):
url = os.environ['TEAMS_URL']
event_message = event['Records'][0]['Sns']['Message']
message_dict = json.loads(event_message)
pipeline_name = message_dict["detail"]["pipeline"]
pipeline_status = message_dict["detail"]["state"]
print(pipeline_name)
msg = {
"text": f"Pipeline: {pipeline_name} has: {pipeline_status}"
}
encoded_msg = json.dumps(msg).encode('utf-8')
resp = http.request('POST',url, body=encoded_msg)
print({
"message": pipeline_name,
"status_code": resp.status,
"response": resp.data
})
MemorySize: 128
Environment:
Variables:
TEAMS_URL: !Ref TeamsURL
Runtime: 'python3.7'
Timeout: 30
Role: !GetAtt NotificationLambdaFunctioneRole.Arn
NotificationLambdaFunctioneRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: 'lambda.amazonaws.com'
Action: 'sts:AssumeRole'
Policies:
- PolicyName: 'customresource'
PolicyDocument:
Statement:
- Effect: Allow
Action:
- 'sns:*'
Resource: '*'
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: '*'
EventRule:
DependsOn: NotificationLambdaFunction
Type: AWS::Events::Rule
Properties:
Description: "EventRule"
EventPattern:
source:
- "aws.codepipeline"
detail-type:
- "CodePipeline Pipeline Execution State Change"
detail:
state:
- "FAILED"
- "SUCCEEDED"
pipeline:
- !Ref CodePipelineName
resources:
- !Sub 'arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${CodePipelineName}'
State: "ENABLED"
Targets:
-
Arn:
Ref: "SNSTopic"
Id: "NotificationTeams"
PermissionLambda:
DependsOn: NotificationLambdaFunction
Type: AWS::Lambda::Permission
Properties:
FunctionName:
Ref: "NotificationLambdaFunction"
Action: "lambda:InvokeFunction"
Principal: "sns.amazonaws.com"
SourceArn: !Ref SNSTopic
SNSTopic:
DependsOn: NotificationLambdaFunction
Type: AWS::SNS::Topic
Properties:
DisplayName: String
Subscription:
- Protocol: lambda
Endpoint: !GetAtt NotificationLambdaFunction.Arn
SnsTopicPolicy:
Type: AWS::SNS::TopicPolicy
DependsOn: SNSTopic
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: SnsTopicPolicy
Effect: Allow
Principal:
AWS: "*"
Action:
- "SNS:GetTopicAttributes"
- "SNS:SetTopicAttributes"
- "SNS:AddPermission"
- "SNS:RemovePermission"
- "SNS:DeleteTopic"
- "SNS:Subscribe"
- "SNS:ListSubscriptionsByTopic"
- "SNS:Publish"
- "SNS:Receive"
Resource:
Ref: SNSTopic
- Sid: SnsTopicPolicyEvent
Effect: Allow
Principal:
Service: "events.amazonaws.com"
Action:
- "SNS:Publish"
Resource:
Ref: SNSTopic
Topics:
- Ref: SNSTopic
In this Cloud Formation template, we have two parameters which need to be updated as per your configuration. One is Incoming Webhook URL from you Microsoft Teams Channel and second AWS Code Pipeline Name. Make sure to update both.
AWS Cloud Formation Deployment
Deploy your AWS Cloud Formation template from your local machine using AWS CLI command, however you can deploy it directly from AWS Cloud Formation page.
aws cloudformation package
--template-file codepipeline-ms-team-notification.yaml
--s3-bucket <MY-PACKAGE-CFN-BUCKET>
--output-template-file your-notification-output.yaml
aws cloudformation deploy
--template-file codepipeline-ms-team-notification.yaml
--stack-name team-notification-cloudformation-stack
--capabilities CAPABILITY_NAMED_IAM
Thanks for reading!