Statistics
6
Views
0
Downloads
0
Donations
Support
Share
Uploader

高宏飞

Shared on 2026-05-11

AuthorJimmy Ray

In today's cloud native world, where we automate as much as possible, everything is code. With this practical guide, you'll learn how Policy as Code (PaC) provides the means to manage the policies, related data, and responses to events that occur within the systems we maintain—Kubernetes, cloud security, software supply chain security, infrastructure as code, and microservices authorization, among others. Author Jimmy Ray provides a practical approach to integrating PaC solutions into your systems, with plenty of real-world examples and important hands-on guidance. DevOps and DevSecOps engineers, Kubernetes developers, and cloud engineers will understand how to choose and then implement the most appropriate solutions. Understand PaC theory, best practices, and use cases for security Learn how to choose and use the correct PaC solution for your needs Explore PaC tooling and deployment options for writing and managing PaC policies Apply PaC to DevOps, IaC, Kubernetes, and AuthN/AuthZ Examine how you can use PaC to implement security controls Verify that your PaC solution is providing the desired result Create auditable artifacts to satisfy internal and external regulatory requirements

Tags
No tags
ISBN: 1098139186
Publisher: O'Reilly Media
Publish Year: 2024
Language: 英文
Pages: 557
File Format: PDF
File Size: 10.1 MB
Support Statistics
¥.00 · 0times
Text Preview (First 20 pages)
Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

Jimmy Ray Policy as Code Improving Cloud Native Security
SECURIT Y “This book fills a gap I frequently see in many organizations looking to adopt modern software development practices and the cloud—how to think about automated policy enforcement in a coherent and actionable way. The first chapter alone is worth the price of the book, and it should be mandatory reading for any leader thinking about or struggling with cloud adoption. ” —Mark Donovan Director, WW Technologists, AWS Policy as Code linkedin.com/company/oreilly-media youtube.com/oreillymedia In today’s cloud native world, where we automate as much as possible, everything is code. With this practical guide, you’ll learn how Policy as Code (PaC) provides the means to manage the policies, related data, and responses to events that occur within the systems we maintain — Kubernetes, cloud security, software supply chain security, infrastructure as code, and microservices authorization, among others. Author Jimmy Ray provides a practical approach to integrating PaC solutions into your systems, with plenty of real- world examples and important hands- on guidance. DevOps and DevSecOps engineers, Kubernetes developers, and cloud engineers will understand how to choose and then implement the most appropriate solutions. • Understand PaC theory, best practices, and use cases for security • Learn how to choose and use the correct PaC solution for your needs • Explore PaC tooling and deployment options for writing and managing PaC policies • Apply PaC to DevOps, IaC, Kubernetes, and AuthN/AuthZ • Examine how you can use PaC to implement security controls • Verify that your PaC solution is providing the desired result • Create auditable artifacts to satisfy internal and external regulatory requirements Underpinned by 30 years of technology, writing, and speaking experience, Jimmy Ray is recognized as a subject-matter expert in Policy as Code, cloud native computing, and software supply chain security. 9 7 8 1 0 9 8 1 3 9 1 8 6 5 7 9 9 9 US $79.99 CAN $99.99 ISBN: 978-1-098-13918-6
Praise for Policy as Code This book fills a gap I frequently see in many organizations looking to adopt modern software development practices and the cloud—how to think about automated policy enforcement in a coherent and actionable way. The first chapter alone is worth the price of the book and it should be mandatory reading for any leader thinking about or struggling with cloud adoption. —Mark Donovan, Director, WW Technologists, AWS Policy as Code is transforming SecOps, just as infrastructure as code has transformed DevOps! In this book, Jimmy Ray provides a fantastic foundation of PaC principles and a comprehensive tour of solutions for platform engineers looking to build secure self-service for developers and data scientists. —Jim Bugwadia, Cochair, CNCF Kubernetes Policy Working Group, Cofounder and CEO, Nirmata Jimmy Ray has really poured his heart and soul into this book, covering the journey of Policy as Code in the OSS community from humble beginnings to wider adoption as a key guardrail in protecting and governing the end state. I found it full of practical examples and technical details that provide insight into the various Policy as Code solutions. —Jesse Loudon, Tech Stream Lead (Azure), Arinco, and Microsoft MVP (Azure)
Governance as code is a deep subject which every CIO or CTO will need to implement. Jimmy Ray breaks down the subject matter, making it easy to understand, and gives the reader all the tools necessary to be successful in its roll out. —Darien Ford, CTO, Madhive
Jimmy Ray Policy as Code Improving Cloud Native Security Boston Farnham Sebastopol TokyoBeijing
978-1-098-13918-6 [LSI] Policy as Code by Jimmy Ray Copyright © 2024 Jimmy Ray. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://oreilly.com). For more information, contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com. Acquisitions Editor: Simina Calin Development Editor: Melissa Potter Production Editor: Elizabeth Faerm Copyeditor: Shannon Turlington Proofreader: Brandon Hashemi Indexer: Ellen Troutman-Zaig Interior Designer: David Futato Cover Designer: Karen Montgomery Illustrator: Kate Dullea July 2024: First Edition Revision History for the First Edition 2024-07-02: First Release See http://oreilly.com/catalog/errata.csp?isbn=9781098139186 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Policy as Code, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc. The views expressed in this work are those of the author and do not represent the publisher’s views. While the publisher and the author have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the author disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights.
Table of Contents Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi 1. Policy as Code: A Gentle Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 What Is Policy? 2 What Is Policy as Code? 3 What Is a Policy? 3 PaC Policy Characteristics 4 The Role of JSON and YAML 4 Guardrails: Preventing the Unwanted 5 Plans: Reacting to the Unplanned 7 Adopting Open Source Software 8 Disadvantages of OSS 9 The Care and Feeding of OSS 10 Standards and Controls 12 Policy as Code for Everything as Code 14 Policy Engines and Languages 16 Choosing the Right PaC Solution 17 Example PaC Selection Factors 18 PaC Selection Scorecard 20 The Cloud Native Computing Foundation 22 Summary 24 2. Open Policy Agent. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Hello World 26 OPA Installation and Modes 27 OPA Command-Line Interface 29 OPA Read-Eval-Print Loop 30 OPA Server 33 v
OPA eval 40 OPA exec 40 Rego Policy Language 41 OPA Document Model 42 Rego Syntax and Logic 43 Writing and Testing Rego 49 The Rego Playground 53 Advanced Bundling Topics 56 Bundle Signing 56 Bundles for Extension: WebAssembly 58 Extending and Integrating with OPA 59 Summary 60 3. Policy as Code and Access Control. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Privileged Access Management 62 OPA Bearer Token AuthN and AuthZ 62 Role-Based Access Control 65 OPA and RBAC 68 Attribute-Based Access Control 74 OPA and ABAC 75 Administering Policies and Data 80 Bundle Server 80 Styra DAS and Policy-Based Access Management 84 Styra Run 89 Open Policy Administration Layer 90 Using OCI Images with OPA and Open Policy Containers 93 Summary 97 4. Policy as Code and Kubernetes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 CNCF and Policy Management 100 Implementing Security Controls and Controlling Behaviors 100 API Server Requests 101 Admission Controllers 102 Dynamic Admission Controllers 103 Mutating Resources 112 Validating Resources 114 API Server Request Latency and Webhook Order 115 Auditing and Background Scanning Existing Resources 116 Generating Resources and Policies 117 Kubernetes Native Policy Features 118 Pod Security 118 Pod Security Admission 119 vi | Table of Contents
Validating Admission Policy 123 AuthZ Webhook Mode 126 AuthZ Decisions 127 AuthZ Webhook and PaC 128 Example Policy 129 Policy Reporting 131 Summary 133 5. Open Policy Agent and Kubernetes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 OPA Installation 136 Validating Admission Webhook 137 Kubernetes Management Sidecar 147 Kubernetes Policy Management 147 Kubernetes Data Management 148 Data from Configmaps 150 OPA AuthZ and kube-mgmt 151 Kubernetes Policies 154 Validation Policies 155 OPA Policy Entry Point 157 Custom Helper Libraries 159 Mutating Configuration and Policies 163 Centralized OPA Management with Styra DAS 167 Policy Management 169 Uninstalling Styra DAS 172 Summary 174 6. MagTape and Kubernetes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Installing and Uninstalling MagTape 178 MagTape init 184 Proxying OPA with MagTape 185 Controlling Deny Volumes 186 The Deny Volume Knob 189 Slack Notifications 190 Summary 191 7. OPA/Gatekeeper and Kubernetes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 Installation 194 Ignoring Namespaces 196 Config: Alpha Feature 198 Uninstalling Gatekeeper 199 Policies 200 OPA Constraint Framework 200 Table of Contents | vii
Validation Policies 201 Enforcement Actions 207 Mutation Policies 208 Use Case: Multitenancy Isolation 214 Audit Mode 220 External Data Providers 223 Policy Expansion 230 Policy Testing 232 Summary 234 8. Kyverno and Kubernetes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 Installation 238 Ignoring Namespaces 240 Dynamic Webhook Configurations 241 Uninstalling Kyverno 243 Policies 244 Policy Lexicon 246 Policy Composition 248 Policy Types 251 Policy Reporting 277 Background Scans 279 Policy Testing 281 Summary 287 9. jsPolicy and Kubernetes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 Installation 290 CRD Webhook Configuration 292 Policy Webhook Configurations 293 Uninstalling jsPolicy 296 Policies 298 Inline Policies 298 Bundled Policies 311 Summary 314 10. Cloud Custodian and Kubernetes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 CLI Mode 316 Installation 316 Cleanup 318 Policies 319 Policies with Actions 323 Discovery with Policies 325 Controller Mode 329 viii | Table of Contents
Installation 329 Validating Policies 333 Mutating Policies 334 c7n-kates 336 Summary 340 11. PaC and Infrastructure as Code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 Infrastructure as Code 344 Immutability 345 Baking Versus Frying 346 Imperative and Declarative IaC 347 Applying PaC to IaC 350 Preventive Controls 351 Conftest 356 Checkov and cfn-lint 358 CFN Hooks 363 Using PaC with Hooks 365 Validating Terraform 368 Terraform and Conftest 369 OPA tfplan 373 Summary 376 12. PaC and Terraform IaC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 HashiCorp Sentinel 379 Terraform Artifacts 382 Mocking Data 383 Testing 390 Running Policies in TFC 400 Additional Terraform Validation 401 Checkov 402 tflint 403 Terrascan 404 tfsec 405 Snyk 407 Summary 411 13. PaC and Infrastructure as a Service. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413 Prowler 414 Prowler Checks 414 Prowler CLI 416 Cloud Custodian 422 Installation 422 Table of Contents | ix
Cleanup 423 Cloud Custodian Policies 424 FinOps with Custodian 441 Summary 446 14. PaC and the Software Supply Chain. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 Attacking Normal 449 SSC Policy Enforcement Points 451 Codebase and Pipeline PEPs 452 PaC and Trivy with Container Images 463 Software Bill of Materials 465 Evaluating SBOMs with PaC 467 Detecting Vulnerabilities in SBOMs with PaC 468 SBOM Promises 471 SBOM Authenticity and Integrity 472 Summary 476 15. Retrospectives and Futures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 Characteristics of Successful PaC Adoption 480 Momentum 480 Domain-Specific Languages 481 Usability 482 Project Extensibility and Ecosystem Development 484 Enterprise Solutions 485 PaC Looking Forward 486 Embracing Standards with OSCAL 486 PaC and Generative AI 490 Cedar 500 Configure, Unify, Execute 502 Conclusion 507 Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509 x | Table of Contents
Preface In 2016, I was tasked with writing cloud computing controls as part of a large cloud- migration effort. These controls were based on standards adopted by—and created within—our organization, and they prevented unwanted and potentially dangerous changes within our cloud environments. I started writing the controls using what I thought was the best tool in my toolbox, Java; I was a Java subject matter expert (SME), and the cloud service provider (CSP) offered a mature Java software development kit (SDK). The first and, as it turns out, last control I wrote in Java enforced encryption of data at rest on object storage. There are certain control types within cloud computing that I consider fundamental for secure computing, and encryption of data at rest and data in transit tops my list. I quickly realized that building and running individual programs or modules to implement controls for the vast collection of cloud computing services and their respective features was not scalable or easily supportable. Writing code to consume the SDK was too low level. I was moving too slow, and it was challenging for me to share my approach in a way that facilitated broad adoption. The standards and con‐ trols SMEs were not Java programmers, and I couldn’t expect them to learn Java just to build new controls or even support those already built. I Needed Policy as Code I needed a more abstract solution—maybe underpinned by a domain-specific lan‐ guage (DSL)—that provided a common lexicon that was more familiar to the folks specifying the cloud computing controls. Regardless of the underlying implementa‐ tion, users defining the controls should be experts in cloud computing controls, not the technology used to implement the controls. The solution I chose was Cloud Custodian (c7n). xi
C7n was developed by a colleague of mine, and over time, it has been broadly adop‐ ted by cloud computing users and providers. With c7n we deployed rules engines to our cloud environments and wrote policies using a controls-friendly YAML DSL. Moreover, the DSL did not require any knowledge of the underlying Python code used to build c7n. C7n was the first Policy as Code (PaC) tool I used. As a point of reference, Policy as Code (PaC)—the focus of this book—is the use of code artifacts to manage and apply rules and conditions. Policy engines are the programs that interpret policy artifacts to apply policy decisions. The rules and conditions defined in policy artifacts help us implement standards and policies that we have created or adopted. These implementations—known as con‐ trols—apply security, compliance, governance, and best-practices decisions that are designed to prevent and react to unwanted changes within the systems we support and use. From that experience I learned that security, compliance, and governance did not need to hinder progress. We wrote policies that served as boundaries between which our cloud engineers worked. These boundaries did not stop them; moreover, our engineers learned the controls they needed to follow, and we reduced unwanted changes into our cloud environments. We managed c7n policies like other code arti‐ facts, employing continuous integration (CI) and continuous delivery (CD) tools to keep our policies and cloud environments updated. PaC solutions allow users to write policies to enforce behaviors. These behaviors are scoped into security, compliance, and governance controls as well as best practices. PaC—with appropriate policies—can reduce or even eliminate nondeterministic behaviors within your artifacts and systems. And when it comes to securing systems, fewer surprises are generally considered a good thing. Who Should Read This Book This book is for DevOps practitioners, Kubernetes cluster operators, security engi‐ neers, and anyone charged with ensuring secure operations in cloud native and everything-as-code environments. In this book, I introduce PaC concepts and use cases, and expose you to patterns and solutions to help you successfully use PaC for your security, compliance, and governance needs. I think this book can serve as a ref‐ erence for those of you needing to understand PaC and choose the right solution for your use cases. You can also use this book to discover techniques and patterns that you can apply immediately. I think some of you will reread this book to gain a deeper understanding of the different aspects of PaC. xii | Preface
For the purposes of this book, I mean to cover PaC and PaC solutions that are, for the most part, vendor neutral and CSP agnostic. By the end of this book, you should bet‐ ter understand PaC theory and capabilities as well as use cases, patterns, and best practices for security, compliance, and governance controls. In Chapter 1, I introduce a process you can use to choose the correct PaC solution for your needs and capabili‐ ties. As you read this book, refer back to the process to better understand each solution and its potential fit for your needs. Conventions Used in This Book The following typographical conventions are used in this book: Italic Indicates new terms, URLs, email addresses, filenames, and file extensions. Constant width Used for program listings, as well as within paragraphs to refer to program ele‐ ments such as variable or function names, databases, data types, environment variables, statements, and keywords. Constant width bold Shows commands or other text that should be typed literally by the user. Constant width italic Shows text that should be replaced with user-supplied values or by values deter‐ mined by context. This element signifies a tip or suggestion. This element signifies a general note. This element indicates a warning or caution. Preface | xiii
Using Code Examples Supplemental material (code examples, etc.) is available for download at https:// github.com/Policy-as-Code-Book. If you have a technical question or a problem using the code examples, please send email to support@oreilly.com. This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission. We appreciate, but generally do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “Policy as Code by Jimmy Ray (O’Reilly). Copyright 2024 Jimmy Ray, 978-1-098-13918-6.” If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at permissions@oreilly.com. O’Reilly Online Learning For more than 40 years, O’Reilly Media has provided technol‐ ogy and business training, knowledge, and insight to help companies succeed. Our unique network of experts and innovators share their knowledge and expertise through books, articles, and our online learning platform. O’Reilly’s online learning platform gives you on-demand access to live training courses, in-depth learning paths, interactive coding environments, and a vast collection of text and video from O’Reilly and 200+ other publishers. For more information, visit https://oreilly.com. xiv | Preface
How to Contact Us Please address comments and questions concerning this book to the publisher: O’Reilly Media, Inc. 1005 Gravenstein Highway North Sebastopol, CA 95472 800-889-8969 (in the United States or Canada) 707-827-7019 (international or local) 707-829-0104 (fax) support@oreilly.com https://www.oreilly.com/about/contact.html We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at https://oreil.ly/policy-as-code. For news and information about our books and courses, visit https://oreilly.com. Find us on LinkedIn: https://linkedin.com/company/oreilly-media. Watch us on YouTube: https://youtube.com/oreillymedia. Acknowledgments Although I am the only author listed on this book, and I set out alone to write this book, I immediately found myself seeking the guidance of those who have gone before me and other industry SMEs. I started this effort while still at AWS, and Michael Hausenblas—my colleague and a prolific author whose books I usually read from cover to cover—helped me get started with O’Reilly and the writing process. It would have been much harder to launch this effort without Michael’s experience and knowledge as my wayfinder. I was lucky enough to receive technical reviews, subject matter expertise, critical feed‐ back, and encouragement from several individuals during the process; I am indebted to them, even if they do not realize it. Anders Eknert, Jesse Loudon, and Rosemary Wang were my first technical reviewers. They were tough, they challenged me to think beyond my perspective and consider the needs of my readers, and they set the bar and my expectations high. They went on to help me throughout the writing of this book with general policy, Kubernetes, and Open Policy Agent (OPA) topics; when it comes to OPA, Rego, and PaC, Anders provided a wealth of valuable infor‐ mation. Within the OPA community Slack channel, Stephan Renatus stands out for helping me answer questions just in time to finish topics. Preface | xv
For MagTape and OPA topics, Joe Searcy was quite helpful. Even though the project is somewhat dormant, that chapter is one of my favorites in this book, as it challenges the status quo of PaC and Kubernetes integration and illustrates the art of the possible. I have known Jim Bugwadia for years, dating back to when I was at Capital One; he and I collaborated on a couple of AWS blogs, efforts for which I also enlisted the help of Chip Zoller. Jim and Chip provided much needed insight into Kubernetes and Kyverno as well as technical reviews on related topics. Together, they helped correct and smooth what I thought I knew. Michael LaPane helped with several complex Terraform topics, and we discussed the book over several sessions at the Crazy Rooster in Powhatan, Virginia, and at his house, consuming BBQ. I spent several hours over the course of writing this book in the Gatekeeper Slack channel, and Sertaç Özercan and Rita Zhang were quite helpful there. Eve Ben Ezra, Michael Hume, and Thomas Lawson provided valuable help and understanding about Conftest in the form of timely KubeCon talks and blog posts. When it came time to write about Cloud Custodian for infrastructure as a service (IaaS) and Kubernetes, Kapil Thangavelu (creator of Cloud Custodian) and David Shepherd—both colleagues from my Capital One days—and AJ Kerrigan readily answered all my questions and helped me stay on the right path. It’s one thing to use a technology; it’s altogether different to be able to write about it with authority. Rich Burroughs—with Loft Labs—helped me with jsPolicy, and Christopher Phillips— another former Capital One colleague, now with Anchore—helped me with SBOMs and the Anchore Syft and Grype tools. When it came to software supply chain topics, I received considerable help from the folks at Liatrio, including Oliver Eikenberry, Robert Kelly, Jonathan Dorsey, Ahmed Alsabag, and Eric Chapman. Liatrio has a wealth of knowledge and experience in the software supply chain space. And, as my chapter on PaC and the software supply chain was one of my last chapters, I received just-in-time help from Cassie Crossley and her newly minted—at the time—book Software Supply Chain Security (O’Reilly). Dan Lorenc helped me distill simplicity from the complex topic of how public key infrastructure is used to apply signatures to artifacts and attestations to create software supply chain statements. I appreciate the experience of building Kubernetes the hard way—using Bash and Go—with my then Capital One colleagues Andrew Myhre and Zach Abrahamson. Lessons I learned then I still use today. I want to thank Mark Donovan, Jeremy Cowan, and Jesse Butler, three outstanding colleagues from AWS—Mark and I go back to my earliest days at Capital One. I am not sure they know how much I rely on their mentorship. xvi | Preface
Writing—like working—is not without sacrifice. Writing a book is a whole other level of sacrifice, and my family was good at not complaining or showing disappointment when I worked to stay on schedule. I learned new techniques to navigate the quiet and dark house as I worked late into the night. Regardless of how I tried not to, I always seemed to wake my wife. I appreciate her forbearance. Finally, none of this would be possible without my O’Reilly team. Melissa Potter is a fan‐ tastic content development editor and one of the main reasons I was able to deliver the content for this book. She and I met regularly, and she helped me understand how to write for O’Reilly, reminding me how best to build content. As I navigated several health- and work-related issues, Melissa was there to encourage me and help with scheduling. Liz Faerm is a production editor, and she routinely rewarded me with my early releases and additional recommendations to improve the structure of my content. Simina Calin— senior acquisition editor—was my primary initial contact with O’Reilly, and she helped me build a strategy and outline for the entire book. Preface | xvii
(This page has no text content)