« Previous 1 2 3 4 Next »
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.
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).
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.
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.
« Previous 1 2 3 4 Next »
Buy this article as PDF
(incl. VAT)