Security in the AWS cloud with GuardDuty

En Garde!

Tomato, Tomahto

So that the terminology is clear, you're initially going to set up a single, standalone GuardDuty master account. This main account ingests member accounts, so you can centrally manage all the alerts (known as findings) from one place. More about master and member GuardDuty accounts can be found online [6].

You can also configure and pull in lots of less privileged users from member accounts who can view findings but can't affect configuration. The bells and whistles example later looks into this case further. If you're curious from a Terraform perspective, you can find more information online [7].

The code in Listing 2 is my variables.tf file. For your use, you should alter the email address and AWS account number. (Look under Billing in the AWS Console for the account number.)

Listing 2

variables.tf

01 variable "aws_region" {
02   default = "eu-west-1"
03 }
04
05 variable "aws_account" {
06   default = "XXXXXXXXXXXXX"
07 }
08
09 variable "aws_member_account_email_id" {
10   default = "pigeon @ devsecops.cc"
11 }

Listing 3 shows the output.tf file, which I've included so you can make sure you've set GuardDuty up on the correct AWS account.

Listing 3

output.tf

01 output "master_guardduty_account_id" {
02   value = "${aws_guardduty_detector.guardduty_master.account_id}"
03 }

Finally, Listing 4 offers the innards required to enable GuardDuty with Terraform from the main.tf file. This super-simple file saves your Terraform state, enables GuardDuty, and does some minimal configuration.

Listing 4

main.tf

01 provider "aws" {
02   region = "${var.aws_region}"
03 }
04
05 terraform {
06   backend "s3" {
07     region  = "eu-west-1"
08     bucket  = "chrisbinnie-terraformstate"
09     key     = "guardduty.tfstate"
10     encrypt = true
11   }
12 }
13
14 resource "aws_guardduty_detector" "guardduty_master" {
15   enable = true
16 }
17
18 resource "aws_guardduty_member" "member" {
19   account_id  = "${var.aws_account}"
20   detector_id = "${aws_guardduty_detector.guardduty_master.id}"
21   email          = "${var.aws_member_account_email_id}"
22 }

The top of Listing 4 pulls in the AWS region configured in variables.tf. You might want to add that to output.tf, too, because it's easy to set GuardDuty live in the wrong region. The second stanza down points to the S3 bucket (see the "Hole In My Bucket, Delilah" box for the limitations of Terraform and its upsides), where Terraform saves its state file. The final two sections are simply switching GuardDuty on and adding an email address in case member accounts want to be contacted in the future.

Hole In My Bucket, Delilah

The chrisbinnie-terraformstate S3 bucket in the main.tf file relates to the unique bucket name in which the Terraform state file is stored that allows another user to destroy or amend the resources you created with your local Terraform code.

Without this state file or access to your local laptop's copy, the venerable Terraform has no way or rewinding the actions it took and cleaning up the many, sometimes almost completely hidden, AWS resources it calls on during execution.

If you're not convinced about maintaining a remote state file, you should read a nicely written article on why you should definitely care about using an S3 bucket in Terraform [8].

I've mentioned that the code won't run quite yet without creating an S3 bucket first. You'll receive an unceremonious warning, with a handful of confusing asides, that a resource doesn't exist, and after some squinting, you'll probably be able to discern that Terraform is talking about the S3 bucket.

Even though some tools, such as Terragrunt  [9], will apparently create the S3 bucket required for storing state files for you, Terraform doesn't appear to do so currently, because it can't rewind the state of the bucket.

Note that you can't just run this code without creating the S3 bucket first. My bucket is chrisbinnie-terraformstate, and I'll have to create it manually with private permissions before running Terraform. Figure 2 shows that there's no point in giving the entire Internet details of your precious resources, so keep the permissions set to private in the AWS Console if you're using that method to create your bucket.

Figure 2: Keep your S3 bucket permissions set to private or bad things will happen.

If you added some members, use the following variable syntax:

output "member_guardduty_account_id" {
  value = "${aws_guardduty_detector.guardduty_member.account_id}"
}

This is the output.tf version.

Next, Please

Once I have a back-end S3 bucket created and secured in the correct region, I can then enter the Terraform code directory and run the command:

$ terraform init

The resulting and very welcome message, among other output, is Terraform has been successfully initialized!

Now, you can run the terraform plan command, as discussed earlier. Figure  3 offers the result of your planning. Now that it's working without errors, you can run terraform apply, and as a result, GuardDuty should be configured automatically for you (Figure  4).

Figure 3: The successful output from the terraform plan command.
Figure 4: The abbreviated success message after applying the plan.

Don't be fooled, however; you haven't created just two resources: AWS is weaving its magic behind the scenes. In Terraform terms, it's very clean to visualize, though.

Regions

If you see the AWS Console screen shown in Figure 5, you haven't enabled GuardDuty in that region, which of course you might have intended to do. The nice thing about Infrastructure as Code is that it's relatively easy to reiterate your actions across many regions. Consider that Figure 5 is showing GuardDuty switched off; that is, no detector is running.

Figure 5: What? No GuardDuty? If you see the Get started button, it's switched off in that region.

If you mistakenly use the wrong region, fear not. Check Disable GuardDuty (Figure 6) under the Settings option within GuardDuty in the AWS Console, and you'll see the screen in Figure 5 showing it's not present once again after a page reload.

Figure 6: If you make a mistake, just go into the AWS Console and check Disable GuardDuty to prevent ongoing charges.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus