Skip to content

Commit 0a05954

Browse files
committed
General cleanup, check for aws-cloud plugin before attempting backup, make cron schedule configurable
1 parent 1fe2705 commit 0a05954

File tree

8 files changed

+82
-48
lines changed

8 files changed

+82
-48
lines changed

Dockerfile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
FROM quay.io/aptible/alpine:latest
2-
RUN apk update && apk-install curl
3-
ADD elasticsearch-backup.crontab /opt/elasticsearch-backup.crontab
4-
RUN crontab /opt/elasticsearch-backup.crontab
5-
ADD src/ /opt/script
2+
RUN apk update && apk-install coreutils curl
3+
ADD . /opt/app
4+
WORKDIR /opt/app/src
65
CMD ["/bin/bash"]

Procfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
cron: crond && tail -F /var/log/cron.log
1+
cron: /bin/bash /opt/app/src/run-cron.sh

README.md

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,23 @@ Elasticsearch snapshot in your S3 snapshot repository.
1111

1212
Recommended setup for running as an app on Aptible:
1313

14-
1. Create an S3 bucket for your logs in the same region as your Elasticsearch
14+
1. Make sure your Elasticsearch instance has the
15+
[cloud-aws plugin](https://github.com/elastic/elasticsearch-cloud-aws)
16+
installed. You can check that it's installed by running:
17+
18+
```
19+
grep cloud-aws <(curl ${ELASTICSEARCH_URL}/_cat/plugins 2>/dev/null)
20+
```
21+
22+
If that command prints nothing, you need to [find the appropriate plugin
23+
version for your server](https://github.com/elastic/elasticsearch-cloud-aws#aws-cloud-plugin-for-elasticsearch)
24+
and install it.
25+
26+
2. Create an S3 bucket for your logs in the same region as your Elasticsearch
1527
database.
1628
17-
2. Create an IAM user to run the backup and restore. Give your IAM user
18-
permission to read/write from the bucket you created in step 1. The
29+
3. Create an IAM user to run the backup and restore. Give your IAM user
30+
permission to read/write from the bucket you created in step 2. The
1931
elasticsearch-cloud-aws plugin documentation has [instructions on setting
2032
up these permissions](https://github.com/elastic/elasticsearch-cloud-aws/tree/v2.5.1/#recommended-s3-permissions);
2133
adding the following as an inline custom policy should be sufficient
@@ -55,24 +67,33 @@ Recommended setup for running as an app on Aptible:
5567
5668
```
5769
58-
3. Create an app in your [Aptible dashboard](https://dashboard.aptible.com) for
59-
the cron. In the steps that follow, we'll use &lt;YOUR_APP_HANDLE&gt;
60-
anywhere that you should substitute the actual app handle the results from
61-
this step in the instructions.
70+
4. Create an app in your Aptible account for the cron. You can do this through
71+
the [Aptible dashboard](https://dashboard.aptible.com) or using the
72+
[Aptible CLI](https://github.com/aptible/aptible-cli):
6273
63-
4. Use the [Aptible CLI](https://github.com/aptible/aptible-cli) to set the
64-
following environment variables in your app:
74+
```
75+
aptible apps:create YOUR_APP_HANDLE
76+
```
77+
78+
In the steps that follow, we'll use &lt;YOUR_APP_HANDLE&gt; anywhere that
79+
you should substitute the actual app handle you've specified in this step.
80+
81+
5. Set the following environment variables in your app's configuration:
6582
6683
* `DATABASE_URL`: Your Elasticsearch URL.
6784
* `S3_BUCKET`: Your S3 Bucket name.
68-
* `S3_ACCESS_KEY_ID`: The access key you generated in step 2.
69-
* `S3_SECRET_ACCESS_KEY`: The secret key you generated in step 2.
85+
* `S3_ACCESS_KEY_ID`: The access key you generated in step 3.
86+
* `S3_SECRET_ACCESS_KEY`: The secret key you generated in step 3.
7087
71-
In addition, the following environment variables are optional:
88+
You may also wish to override any of the following optional environment
89+
variables:
7290
7391
* `MAX_DAYS_TO_KEEP`: The number of days of live logstash indexes you'd
7492
like to keep in your Elasticsearch instance. Any indexes from before this
7593
point will be archived by the cron. Defaults to 30.
94+
* `CRON_SCHEDULE`: The schedule for your backups. Defaults to "0 2 * * *",
95+
which runs nightly at 2 A.M. Make sure to escape any asterisks when
96+
setting this variable from the command line to avoid shell expansion.
7697
* `S3_REGION`: The region your Elasticsearch instance and S3 bucket live in.
7798
Defaults to `us-east-1`.
7899
* `REPOSITORY_NAME`: The name of your Elasticsearch snapshot repo. This is
@@ -87,7 +108,7 @@ Recommended setup for running as an app on Aptible:
87108
aptible config:set NAME=VALUE --app YOUR_APP_HANDLE
88109
```
89110
90-
5. Clone this repository and push it to your Aptible app:
111+
6. Clone this repository and push it to your Aptible app:
91112
92113
```
93114
git clone https://github.com/aptible/elasticsearch-logstash-s3-backup.git
@@ -100,28 +121,31 @@ Recommended setup for running as an app on Aptible:
100121
101122
The cron run by this app will execute daily and log its progress to stdout.
102123
103-
To restore an index, you can use the `restore-index.sh` script included in this
104-
repository. Just use the Aptible CLI to SSH into an app container:
124+
To test the backup or run it manually, use the Aptible CLI to run the
125+
`backup-all-indexes.sh` script in a container over SSH:
105126
106127
```
107-
aptible ssh --app YOUR_APP_HANDLE
128+
aptible ssh --app YOUR_APP_HANDLE ./backup-all-indexes.sh
108129
```
109130
110-
And, from there, run `restore-index.sh` with the name of the index you want to
111-
restore, for example:
131+
To restore an index, you can use the `restore-index.sh` script included in this
132+
repository with the Aptible CLI. For example, to load the index for July 10, 2015,
133+
run:
112134
113135
```
114-
# /bin/bash /opt/scripts/restore-index.sh logstash-2015-07-09
136+
aptible ssh --app YOUR_APP_HANDLE ./restore-index.sh logstash-2015-07-10
115137
```
116138
117139
This will load the index back into your Elasticsearch instance. Note that if
118140
you load an archived index into the same instance that you are running this
119141
cron against, the index will get removed at the end of the day. Alternatively,
120142
you can load the index into a different Elasticsearch instance by overriding
121-
the `DATABASE_URL` environment variable:
143+
the `DATABASE_URL` environment variable in an SSH session before you run the
144+
restore script:
122145
123146
```
124-
# DATABASE_URL=https://some-other-elasticsearch /bin/bash /opt/scripts/restory-index.sh logstash-2015-07-09
147+
$ aptible ssh --app YOUR_APP_HANDLE bash
148+
bash-4.3# DATABASE_URL=https://some-other-elasticsearch ./restore-index.sh logstash-2015-07-09
125149
```
126150
127151
## Copyright and License

elasticsearch-backup.crontab

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/backup-all-indexes.sh

100644100755
Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,42 +17,45 @@ backup_index ()
1717
local SNAPSHOT_URL=${REPOSITORY_URL}/${INDEX_NAME}
1818
local INDEX_URL=${DATABASE_URL}/${INDEX_NAME}
1919

20-
grep -q SUCCESS <(curl ${SNAPSHOT_URL} 2>/dev/null)
20+
grep -q SUCCESS <(curl -sS ${SNAPSHOT_URL})
2121
if [ $? -ne 0 ]; then
2222
echo "Scheduling snapshot."
23-
curl --fail -w "\n" -XPUT ${SNAPSHOT_URL} -d "{
23+
curl --fail -w "\n" -sS -XPUT ${SNAPSHOT_URL} -d "{
2424
\"indices\": \"${INDEX_NAME}\",
2525
\"include_global_state\": false
2626
}" || return 1
2727

2828
echo "Waiting for snapshot to finish..."
29-
timeout "${WAIT_SECONDS}" bash -c "until grep -q SUCCESS <(curl ${SNAPSHOT_URL} 2>/dev/null); do sleep 1; done" || return 1
29+
timeout "${WAIT_SECONDS}" bash -c "until grep -q SUCCESS <(curl -sS ${SNAPSHOT_URL}); do sleep 1; done" || return 1
3030
fi
3131

3232
echo "Deleting ${INDEX_NAME} from Elasticsearch."
33-
curl -w "\n" -XDELETE ${INDEX_URL}
33+
curl -w "\n" -sS -XDELETE ${INDEX_URL}
3434
}
3535

36-
# Ensure that the snapshot repository exists.
37-
REPO_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" ${REPOSITORY_URL})
38-
if [ "$REPO_EXISTS" != 200 ]; then
39-
echo "Creating repository ${REPOSITORY_NAME} to store snapshots..."
40-
curl -w "\n" -XPUT ${REPOSITORY_URL} -d "{
41-
\"type\": \"s3\",
42-
\"settings\": {
43-
\"bucket\" : \"${S3_BUCKET}\",
44-
\"access_key\": \"${S3_ACCESS_KEY_ID}\",
45-
\"secret_key\": \"${S3_SECRET_ACCESS_KEY}\",
46-
\"region\": \"${S3_REGION}\",
47-
\"protocol\": \"https\",
48-
\"server_side_encryption\": true
49-
}
50-
}"
36+
# Ensure that Elasticsearch has the cloud-aws plugin.
37+
grep -q cloud-aws <(curl -sS ${DATABASE_URL}/_cat/plugins)
38+
if [ $? -ne 0 ]; then
39+
echo "Elasticsearch server does not have cloud-aws plugin installed. Exiting."
40+
exit 1
5141
fi
5242

43+
echo "Ensuring Elasticsearch snapshot repository ${REPOSITORY_NAME} exists..."
44+
curl -w "\n" -sS -XPUT ${REPOSITORY_URL} -d "{
45+
\"type\": \"s3\",
46+
\"settings\": {
47+
\"bucket\" : \"${S3_BUCKET}\",
48+
\"access_key\": \"${S3_ACCESS_KEY_ID}\",
49+
\"secret_key\": \"${S3_SECRET_ACCESS_KEY}\",
50+
\"region\": \"${S3_REGION}\",
51+
\"protocol\": \"https\",
52+
\"server_side_encryption\": true
53+
}
54+
}"
55+
5356
CUTOFF_DATE=$(date --date="${MAX_DAYS_TO_KEEP} days ago" +"%Y.%m.%d")
5457
echo "Archiving all indexes with logs before ${CUTOFF_DATE}."
55-
for index_name in $(curl ${DATABASE_URL}/_cat/indices/logstash-* 2>/dev/null | cut -d' ' -f3); do
58+
for index_name in $(curl -sS ${DATABASE_URL}/_cat/indices/logstash-* | cut -d' ' -f3); do
5659
if [[ "${index_name:9}" < "${CUTOFF_DATE}" ]]; then
5760
echo "Ensuring ${index_name} is archived..."
5861
backup_index ${index_name}
@@ -63,3 +66,4 @@ for index_name in $(curl ${DATABASE_URL}/_cat/indices/logstash-* 2>/dev/null | c
6366
fi
6467
fi
6568
done
69+
echo "Finished archiving."

src/backup.crontab.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CRON_SCHEDULE set -a && . /opt/app/.aptible.env && /bin/bash /opt/app/src/backup-all-indexes.sh >> /var/log/cron.log 2>&1

src/restore-index.sh

100644100755
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ if [ -z "$1" ]; then
88
fi
99

1010
REPOSITORY_URL=${DATABASE_URL}/_snapshot/${REPOSITORY_NAME}
11-
curl -XPOST ${REPOSITORY_URL}/$1/_restore
11+
curl -w "\n" -XPOST ${REPOSITORY_URL}/$1/_restore

src/run-cron.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
CRON_SCHEDULE=${CRON_SCHEDULE:-"0 2 * * *"}
3+
sed "s:CRON_SCHEDULE:${CRON_SCHEDULE}:g" /opt/app/src/backup.crontab.template > /opt/app/src/backup.crontab
4+
crontab /opt/app/src/backup.crontab
5+
touch /var/log/cron.log
6+
crond
7+
tail -f /var/log/cron.log

0 commit comments

Comments
 (0)