Skip to content

Commit

Permalink
MON-129 update go src path
Browse files Browse the repository at this point in the history
  • Loading branch information
xp-1000 committed May 8, 2018
0 parents commit e3245b6
Show file tree
Hide file tree
Showing 3 changed files with 331 additions and 0 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018 Claranet

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
214 changes: 214 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
# Zabbix Deregister for AWS AutoScaling

Disable or Delete host from zabbix automatically when AWS autoscaling group terminates its corresponding instance:
Cloudwatch event rule catchs the scale down event from autoscaling group then run a lambda function which will connect to Zabbix API to update host.

## Zabbix configuration

### Administration

1/ Create a new User Group [Administration > User Groups > Create user group]

```
User group:
Group name: AWS AutoScaling Deregister
Frontend access: Disabled
Enabled: [x]
Permissions:
Host Group: [All Host Groups to manage]
Permission: Read-write
```

2/ Create a User [Administration > Users > Create user]

```
User:
Alias: aws-autoScaling-deregister
Name: AWS AutoScaling Deregister
Surname: aws-autoScaling-deregister
Groups: AWS AutoScaling Deregister (created in step 1)
Password/confirm: (Remember it, you will need it soon)
Permissions:
User type: Zabbix Admin
```

### Server configuration

1/ Create a new template [Configuration > Templates > Create template] named `AWS_Metadata`.

2/ Edit this template [Configuration > Templates > `AWS_Metadata` > Items > Create item] :

```
Name: InstanceID
Type: Zabbix Agent
Key: aws.metadata[instance-id]
Type of information: Character
Update interval (in sec): 90
Populates host inventory field: Alias
Description: AWS InstanceID from metadata
```

3/ Update all auto registration actions used for autoscaling hosts [Configuration > Actions > Auto registration] to add new operations:
* `Set host inventory mode` to `Automatic` (if not already done)
* `Link to templates` to `AWS_Metadata`

### Agent configuration

A new UserParameter needs to be added to retrieve the AWS instanceId:

```shell
echo 'UserParameter=aws.metadata[*],curl -s http://169.254.169.254/latest/meta-data/$1' > /etc/zabbix/zabbix_agentd.d/aws.conf
service zabbix-agent restart
```

## Script preparation

Build and zip `zabbix-aws-deregister.go` :

$ cd go/src/zabbix-aws-deregister && go get && go build && zip zabbix-aws-deregister.zip zabbix-aws-deregister

Or simply use [the zip provided in this repo](https://github.com/claranet/zabbix-aws-deregister/releases/download/v1.0.0/zabbix-aws-deregister_1.0.0_linux_amd64.zip)

## AWS configuration

The following resources should be created :

* IAM policy
* IAM role
* Lambda function
* Cloudwatch event rule

1/ Create the IAM policy `zabbix-aws-deregister` [AWS console > IAM > Policies > Create policy > JSON]:

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogStream"
],
"Resource": [
"arn:aws:logs:eu-west-1:424242424242:log-group:/aws/lambda/zabbix-aws-deregister:*"
],
"Effect": "Allow"
},
{
"Action": [
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:eu-west-1:424242424242:log-group:/aws/lambda/zabbix-aws-deregister:*:*"
],
"Effect": "Allow"
}
]
}
```

2/ Create the IAM role `zabbix-aws-deregister` [AWS console > IAM > Roles > Create role > AWS Service > Lambda] attaching the previously created policy `zabbix-aws-deregister`.

3/ Create the lambda function `zabbix-aws-deregister` [AWS console > Lambda > Functions > Create function > Author from scratch]:

```
Name: zabbix-aws-deregister
Runtime: Go 1.x
Role: Choose an existing role
Existing role: zabbix-aws-deregister
```

4/ Configure the lambda function `zabbix-aws-deregister` as following:

```
Function code:
Code entry type: Upload a .ZIP file
Function package: Upload the zip file previously created from "Script preparation" step
Handler: zabbix-aws-deregister
Environment variables:
ZABBIX_URL: https://zabbix.host.tld/api_jsonrpc.php
ZABBIX_USER: previously created user from "Zabbix administration" step (aws-autoScaling-deregister)
ZABBIX_PASS: previously created password from "Zabbix administration" step
DELETING_HOST: true / false
```

Notice: if `DELETING_HOST` is set to `false` so zabbix hosts are not deleted, only disabled.

5/ Create the cloudwatch event rule [AWS console > Cloudwatch > Events > Rules > Create rule].

a/ Configure Event Source as following :

```
Event Pattern: [x]
Service Name: Auto Scaling
Event Type: Instance Launch and Terminate
Specific instance event(s):
EC2 Instance Terminate Successful
EC2 Instance Terminate Unsuccessful
Any group name: [x]
```

The event pattern should be :

```json
{
"source": [
"aws.autoscaling"
],
"detail-type": [
"EC2 Instance Terminate Successful",
"EC2 Instance Terminate Unsuccessful"
]
}
```

b/ Add a new target `Lambda function`:

```
Function: zabbix-aws-deregister (previously created lambda function)
Configure Input:
Part of the matched event: $.detail
```

c/ Configure rule details:

```
Name: zabbix-aws-deregister
Description: Automatic instance deregistration from zabbix when scale down
State: Enabled
```

## Troubleshooting

To quicly test the lambda function and get result it is possible to create a test event [configure test events > Create a new test event],
it could be named `ScaleDown` and looks like the following json:

```json
{
"Description": "Terminating EC2 instance: i-070fc7ff625f55529",
"Details": {
"Subnet ID": "subnet-5c8fb338",
"Availability Zone": "eu-west-1b"
},
"EndTime": "2018-03-06T19:12:44.047Z",
"RequestId": "0a2fb0a9-18ee-44f2-bace-47309ef8ab79",
"ActivityId": "0a2fb0a9-18ee-44f2-bace-47309ef8ab79",
"Cause": "At 2018-03-06T19:11:33Z a user request update of AutoScalingGroup constraints to min: 0, max: 2, desired: 0 changing the desired capacity from 1 to 0. At 2018-03-06T19:11:42Z an instance was taken out of service in response to a difference between desired and actual capacity, shrinking the capacity from 1 to 0. At 2018-03-06T19:11:42Z instance i-070fc7ff625f55529 was selected for termination.",
"AutoScalingGroupName": "test-asg",
"StartTime": "2018-03-06T19:11:42.182Z",
"EC2InstanceId": "i-070fc7ff625f55529",
"StatusCode": "InProgress",
"StatusMessage": ""
}
```

Then, you just have to click on `Test` button to fire the function, review result message and cloudwatch logs.

## References

* [Zabbix Manual](https://www.zabbix.com/documentation/3.4/start)
* [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)
* [AWS Lambda Golang support](https://aws.amazon.com/fr/blogs/compute/announcing-go-support-for-aws-lambda/)

## License

Copyright (c) 2018 Claranet. Available under the MIT License.
96 changes: 96 additions & 0 deletions zabbix-aws-deregister.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package main

import (
"fmt"
"os"
"strconv"

"github.com/AlekSi/zabbix"
"github.com/aws/aws-lambda-go/lambda"
)

type AutoscalingEvent struct {
InstanceId string `json:"EC2InstanceId"`
EndTime string `json:"EndTime"`
StartTime string `json:"StartTime"`
AutoScalingGroupName string `json:"AutoScalingGroupName"`
Cause string `json:"Cause"`
ActivityId string `json:"ActivityId"`
RequestId string `json:"RequestId"`
Description string `json:"Description"`
StatusCode string `json:"StatusCode"`
}

type Configuration struct {
Url string
User string
Password string
Deleting bool
}

func HandleRequest(event AutoscalingEvent) (string, error) {
var ok bool
var err error
configuration := Configuration{
// Url: os.Getenv("ZABBIX_URL"),
// User: os.Getenv("ZABBIX_USER"),
// Password: os.Getenv("ZABBIX_PASS"),
// Deleting: deletingHost,
}
configuration.Url, ok = os.LookupEnv("ZABBIX_URL")
if !ok {
panic("ZABBIX_URL not set")
}
configuration.User, ok = os.LookupEnv("ZABBIX_USER")
if !ok {
panic("ZABBIX_USER not set")
}
configuration.Password, ok = os.LookupEnv("ZABBIX_PASS")
if !ok {
panic("ZABBIX_PASS not set")
}
configuration.Deleting, err = strconv.ParseBool(os.Getenv("DELETING_HOST"))
if err != nil {
panic(err)
}

searchInventory := make(map[string]string)
searchInventory["alias"] = event.InstanceId

api := zabbix.NewAPI(configuration.Url)
_, err = api.Login(configuration.User, configuration.Password)
if err != nil {
panic(err)
}
res, err := api.HostsGet(zabbix.Params{
// "hostids": []string{"100040"},
"output": []string{"host"},
"selectInventory": []string{"alias"},
"searchInventory": searchInventory,
})
if err != nil {
panic(err)
}
for _, host := range res {
if configuration.Deleting {
err := api.HostsDeleteByIds([]string{host.HostId})
if err != nil {
panic(err)
}
} else {
_, err := api.Call("host.update", zabbix.Params{
"hostid": host.HostId,
"status": 1,
})
if err != nil {
panic(err)
}
}
}

return fmt.Sprintf("Zabbix host correspondig to AWS instanceid %s has been disabled", event.InstanceId), nil
}

func main() {
lambda.Start(HandleRequest)
}

0 comments on commit e3245b6

Please sign in to comment.