Which component of an aws cloudformation template consists strictly of key/value pairs?
AWS CloudFormation Hooks Edit Show
AWS CloudFormation Hooks allows users to verify AWS infrastructure components defined in AWS CloudFormation templates, like S3 Buckets or EC2 instances, prior to deployment. This is done via hooks. Hooks are composed of custom code running in an AWS Lambda function, which is invoked before a resource is created, updated or deleted. AWS currently supports hooks written in either Java or Python, and provides a sample repository, which includes example hooks written in both languages. Since we’d rather use OPA for this purpose, we’d need some code to process the requests handled by the hook and send them forward to OPA for policy decisions via its REST API using the OPA AWS CloudFormation Hook. GoalsThis tutorial shows how to deploy an AWS CloudFormation Hook that forwards requests to OPA for policy decisions, allowing us to use policy to determine whether a request to create, update or delete a resource should be allowed or denied. We’ll learn how to author policies that take the input structure of CloudFormation Templates into account, and some special considerations to be aware of in this environment. In addition, this tutorial shows how we can leverage dynamic policy composition to group and structure our policies in a way that follows the domain to which they apply. PrerequisitesIn order to complete this tutorial, the following prerequisites needs to be met:
Steps1. Install the CloudFormation HookTo start out, clone the OPA AWS CloudFormation Hook repository:
To install (but not activate) the hook provided in this repository into your AWS account, cd into the
When the command above is finished (this may take several minutes), you should see output similar to this:
2. Configure the OPA AWS CloudFormation HookThe hook is now installed but needs to be configured for your environment. First, copy the value of the
Next, set the AWS region and the URL to use for calling OPA:
(OPTIONAL): If you want to use a bearer token to authenticate against OPA, provide an ARN pointing to the AWS Secret containing the token:
With the configuration variables set, push the configuration to AWS (remove
The hook is now installed, configured and activated! 3. Learn the DomainBefore we proceed to write our first policy, let’s take a closer look at the data we’ll be working with. AWS CloudFormation TemplatesA template file is commonly a YAML or JSON file, describing a set of AWS resources. While a template may describe multiple resources, the hook will send each resource for validation separately. Important to note here is that the resource presented to the hook will be shown exactly as provided in the template file. The hook does not perform any type preprocessing, such as adding default values where missing, or providing auto-generated names. Policy authors must hence take into account that even “obvious” attributes like name might not be present in the resource provided for evaluation. As an example, a template to deploy an S3 Bucket with default attributes may be as minimal as this:
For more information on templates, see the AWS User Guide on that topic. Input and Response FormatThe OPA configured to receive requests from the CFN hook will have its input provided in this format:
The hook expects the response to contain a boolean
Any request denied will be logged in AWS CloudWatch for the same account. 4. Write a CloudFormation Hook PolicyWith
knowledge of the domain and the data model, we’re ready to write our first CloudFormation Hook policy. Since we’ll have a single OPA endpoint servicing requests for all types of resources, we’ll use the default decision policy, which by default queries the
Since we know that CloudFormation Templates may contain only the bare minimum of information, we can’t assume that there will be an
This rule would work fine as long as there is an Surprisingly, boolean values from CloudFormation Templates are provided to the hook in the form of strings (i.e. “true” and “false”). Policy authors must take this into account, and explicitly check for the value of these attributes. An example S3 bucket policy might for example want to check that public ACLs are blocked:
5. Policy Enforcement TestingWith the above policy loaded into OPA, we may proceed to try it out. Let’s deploy the minimal S3 Bucket
from the previous template example. Save the below minimal template to a file called
Since our S3 bucket doesn’t have an
The output of the above command will simply be a confirmation that the stack was deployed. It won’t tell us whether the deployment was successful or not. In order to know that, we’ll need to check the stack events:
The output of the above command will be a list of all events associated with the
Congratulations! You’ve just successfully enforced your first CloudFormation Hook policy using OPA. Let’s update the template so that it passes our policy requirement: s3bucket.yaml
Even though our stack did not create an S3 bucket (as the change got rolled back), the stack still exists. In order to try again, we’ll first need to delete the existing stack:
Now, let’s try again:
Checking the output of
Note: once
our stack is successfully deployed, we can use the
Further ImprovementsDynamic Policy CompositionHaving a single policy file for all rules will quickly become unwieldy. Could we improve this somehow? One way of doing that would be to use dynamic policy composition, where a single main policy acts as a “router”, and forwards queries to other packages based on attributes from the input. A natural attribute to use for CloudFormation templates might for example be the resource type, allowing us to group our policies by the resource type they’re meant to act on. Let’s take a look at what such a main policy might look like: main.rego
The above
policy will invoke the Since most of our policies will only deal with Additionally, we’ll also do some simple input validation at this stage, so that we may avoid doing so in our resource specific policies. We can now modify our original policy to verify S3 bucket resources only:
Note how we no longer need the OPA Authentication via AWS SecretsOPA ConfigurationSince the OPA server does not run inside the AWS Lambda, it is a good idea to require authentication to access its REST API, as described in the OPA documentation. A simple authz policy for checking the bearer token might look something like this: authz.rego
Once created, remember to pass the appropriate flags to
OPA AWS CloudFormation Hook ConfigurationIf configured to use a bearer token for authenticating against OPA (by setting the In order to fetch the token, the hook will need to be permitted to perform the
If you aren’t planning to use bearer tokens for authentication, you may remove the permission entirely. What are the elements of an AWS CloudFormation template?CloudFormation supports creating VPCs, subnets, gateways, route tables and network ACLs as well as creating resources such as elastic IPs, Amazon EC2 Instances, EC2 security groups, auto scaling groups, elastic load balancers, Amazon RDS database instances and Amazon RDS security groups in a VPC.
What part of a CloudFormation template allows you to pass values into the template?The Resources section is the only required section. Some sections in a template can be in any order. However, as you build your template, it can be helpful to use the logical order shown in the following list because values in one section might refer to values from a previous section.
Which part of the CloudFormation template allows a customer to pass keys and associated values that specify conditional parameter values?Mappings (optional)
The mapping of keys and associated values that can be used to specify conditional parameter values. For instance, with mappings, you can define AMIs available for a specific region.
Which type of AWS CloudFormation function can be used to refer to a value in a comma delimited list?You use the Ref intrinsic function to reference a parameter, and AWS CloudFormation uses the parameter's value to provision the stack.
|