GithubHelp home page GithubHelp logo

trussworks / terraform-aws-wafv2 Goto Github PK

View Code? Open in Web Editor NEW
104.0 12.0 57.0 348 KB

Creates a WAF using AWS WAFv2 and AWS Managed Rule Sets

Home Page: https://registry.terraform.io/modules/trussworks/wafv2

License: Apache License 2.0

HCL 100.00%
aws aws-wafv2 aws-cloudfront aws-alb terraform

terraform-aws-wafv2's Introduction

terraform-aws-wafv2

Creates AWS WAFv2 ACL and supports the following

  • AWS Managed Rule Sets
  • Associating with Application Load Balancers (ALB)
  • Blocking IP Sets
  • Global IP Rate limiting
  • Custom IP rate limiting for different URLs

Usage with CloudFront

Note: The Terraform AWS provider needs to be associated with the us-east-1 region to use with CloudFront.

module "cloudfront_wafv2" {
  source  = "trussworks/wafv2/aws"
  version = "0.0.1"

  name  = "cloudfront-web-acl"
  scope = "CLOUDFRONT"
}

Usage with Application Load Balancer (ALB)

module "alb_wafv2" {
  source  = "trussworks/wafv2/aws"
  version = "0.0.1"

  name  = "alb-web-acl"
  scope = "REGIONAL"

  alb_arn       = aws_lb.alb.arn
  associate_alb = true
}

Usage with Logging Configuraion of CloudWatchLogs

module "alb_wafv2" {
  source  = "trussworks/wafv2/aws"
  version = "0.0.1"

  name  = "cloudfront-web-acl"
  scope = "CLOUDFRONT"

  enable_logging = true
  log_destination_arns = [
    aws_cloudwatch_log_group.logs.arn
  ]
}

Usage blocking IP Sets

resource "aws_wafv2_ip_set" "ipset" {
  name = "blocked_ips"

  scope              = "REGIONAL"
  ip_address_version = "IPV4"

  addresses = [
    "1.2.3.4/32",
    "5.6.7.8/32"
  ]
}

module "wafv2" {
  source = "../../"

  name   = "wafv2"
  scope = "REGIONAL"

  ip_sets_rule = [
    {
      name       = "blocked_ips"
      action     = "block"
      priority   = 1
      ip_set_arn = aws_wafv2_ip_set.ipset.arn
    }
  ]
}

Requirements

Name Version
terraform >= 1.0
aws >= 5.0

Providers

Name Version
aws >= 5.0

Modules

No modules.

Resources

Name Type
aws_wafv2_web_acl.main resource
aws_wafv2_web_acl_association.main resource
aws_wafv2_web_acl_logging_configuration.main resource

Inputs

Name Description Type Default Required
alb_arn ARN of the ALB to be associated with the WAFv2 ACL. string "" no
associate_alb Whether to associate an ALB with the WAFv2 ACL. bool false no
default_action The action to perform if none of the rules contained in the WebACL match. string "allow" no
enable_logging Whether to associate Logging resource with the WAFv2 ACL. bool false no
filtered_header_rule HTTP header to filter . Currently supports a single header type and multiple header values. object({ header_types = list(string) priority = number header_value = string action = string search_string = string }) { "action": "block", "header_types": [], "header_value": "", "priority": 1, "search_string": "" } no
group_rules List of WAFv2 Rule Groups. list(object({ name = string arn = string priority = number override_action = string })) [] no
ip_rate_based_rule A rate-based rule tracks the rate of requests for each originating IP address, and triggers the rule action when the rate exceeds a limit that you specify on the number of requests in any 5-minute time span object({ name = string priority = number limit = number action = string response_code = optional(number, 403) }) null no
ip_rate_url_based_rules A rate and url based rules tracks the rate of requests for each originating IP address, and triggers the rule action when the rate exceeds a limit that you specify on the number of requests in any 5-minute time span list(object({ name = string priority = number limit = number action = string response_code = optional(number, 403) search_string = string positional_constraint = string })) [] no
ip_sets_rule A rule to detect web requests coming from particular IP addresses or address ranges. list(object({ name = string priority = number ip_set_arn = string action = string response_code = optional(number, 403) })) [] no
log_destination_arns The Amazon Kinesis Data Firehose, Cloudwatch Log log group, or S3 bucket Amazon Resource Names (ARNs) that you want to associate with the web ACL. list(string) [] no
managed_rules List of Managed WAF rules. list(object({ name = string priority = number override_action = string vendor_name = string version = optional(string) rule_action_override = list(object({ name = string action_to_use = string })) })) [ { "name": "AWSManagedRulesCommonRuleSet", "override_action": "none", "priority": 10, "rule_action_override": [], "vendor_name": "AWS" }, { "name": "AWSManagedRulesAmazonIpReputationList", "override_action": "none", "priority": 20, "rule_action_override": [], "vendor_name": "AWS" }, { "name": "AWSManagedRulesKnownBadInputsRuleSet", "override_action": "none", "priority": 30, "rule_action_override": [], "vendor_name": "AWS" }, { "name": "AWSManagedRulesSQLiRuleSet", "override_action": "none", "priority": 40, "rule_action_override": [], "vendor_name": "AWS" }, { "name": "AWSManagedRulesLinuxRuleSet", "override_action": "none", "priority": 50, "rule_action_override": [], "vendor_name": "AWS" }, { "name": "AWSManagedRulesUnixRuleSet", "override_action": "none", "priority": 60, "rule_action_override": [], "vendor_name": "AWS" } ] no
name A friendly name of the WebACL. string n/a yes
scope The scope of this Web ACL. Valid options: CLOUDFRONT, REGIONAL. string n/a yes
tags A mapping of tags to assign to the WAFv2 ACL. map(string) {} no

Outputs

Name Description
web_acl_id The ARN of the WAF WebACL.

Developer Setup

Install dependencies (macOS)

brew install pre-commit go terraform terraform-docs
pre-commit install --install-hooks

terraform-aws-wafv2's People

Contributors

avanti-joshi avatar chrisgilmerproj avatar chtakahashi avatar dawidmalina avatar dependabot[bot] avatar eeeady avatar esacteksab avatar fdmsantos avatar ferrangb7 avatar github-actions[bot] avatar jsclarridge avatar kodiakhq[bot] avatar manoelhc avatar neilharris123 avatar ralren avatar rdhariwal avatar renovate-bot avatar renovate[bot] avatar rpdelaney avatar sheenamt avatar vampire-yuta avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-aws-wafv2's Issues

How to block all managed rules but otherwise allow traffic?

If I set default_action to "block" all traffic is blocked - even traffic that doesn't match a managed rule.
If I set default_action to "allow" all traffic is allowed - even traffic that does match a managed rule.

I see one closed issue related to this. I suspect the answer is that an additional custom "allow" rule with low priority must be created. What is the simplest way to accomplish that with this module?

Why module add many default rule, that did not define in code

Here is my Terraform code

module "alb_wafv2" {
  source  = "trussworks/wafv2/aws"
  version = "2.4.0"

  name  = "${var.project_name}-web-${var.environment}"
  scope = "REGIONAL"

  alb_arn       = var.alb_arn
  associate_alb = true
  group_rules = [
    {
      excluded_rules : [],
      name : aws_wafv2_rule_group.allow_ip.name,
      arn : aws_wafv2_rule_group.allow_ip.arn,
      override_action : "none",
      priority : 11
    }
  ]
  tags = merge(var.common_tags, {
    Name = "${var.project_name}-web-${var.environment}"
  })
}

My rule group has only rule block all requests if its not come from a specific IP set. (Capacity 100).
But when I run plan check change, have many default rule added to WEB ACL ?
And I can't create Webacl, it said

Field: "WEB_ACL",
│   Message_: "Error reason: You exceeded the capacity limit for a rule group or web ACL., field: WEB_ACL, parameter: 1525",
│   Parameter: "1525",
│   Reason: "You exceeded the capacity limit for a rule group or web ACL."

Here is plan change log

# module.waf.module.alb_wafv2.aws_wafv2_web_acl.main will be created
  + resource "aws_wafv2_web_acl" "main" {
      + arn         = (known after apply)
      + capacity    = (known after apply)
      + description = "WAFv2 ACL for my-project-web-dev"
      + id          = (known after apply)
      + lock_token  = (known after apply)
      + name        = "my-project-web-dev"
      + scope       = "REGIONAL"

      + default_action {
          + allow {
            }
        }

      + rule {
          + name     = "AWSManagedRulesAmazonIpReputationList"
          + priority = 20

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesAmazonIpReputationList"
                  + vendor_name = "AWS"
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AWSManagedRulesAmazonIpReputationList"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AWSManagedRulesCommonRuleSet"
          + priority = 10

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesCommonRuleSet"
                  + vendor_name = "AWS"
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AWSManagedRulesCommonRuleSet"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AWSManagedRulesKnownBadInputsRuleSet"
          + priority = 30

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesKnownBadInputsRuleSet"
                  + vendor_name = "AWS"
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AWSManagedRulesKnownBadInputsRuleSet"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AWSManagedRulesLinuxRuleSet"
          + priority = 50

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesLinuxRuleSet"
                  + vendor_name = "AWS"
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AWSManagedRulesLinuxRuleSet"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AWSManagedRulesSQLiRuleSet"
          + priority = 40

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {
                  + name        = "AWSManagedRulesSQLiRuleSet"
                  + vendor_name = "AWS"
                }
            }

          + visibility_config {
              + cloudwatch_metrics_enabled = true
              + metric_name                = "AWSManagedRulesSQLiRuleSet"
              + sampled_requests_enabled   = true
            }
        }
      + rule {
          + name     = "AWSManagedRulesUnixRuleSet"
          + priority = 60

          + override_action {

              + none {}
            }

          + statement {

              + managed_rule_group_statement {

      + visibility_config {
          + cloudwatch_metrics_enabled = true
          + metric_name                = "my-project-web-dev"
          + sampled_requests_enabled   = true
        }
    }

AWS Error: "ManagedRules with name AWSManagedRulesAmazonIpReputationList by vendor AWS does not exist."

When using this module's defaults this error appears during terraform apply:

WAFNonexistentItemException: ManagedRules with name AWSManagedRulesAmazonIpReputationList by vendor AWS does not exist. Please check your inputs

It's odd because the rule is clearly listed here:

My code is:

module "alb_wafv2" {
  source  = "trussworks/wafv2/aws"
  version = "2.0"

  name  = "alb-web-acl"
  scope = "REGIONAL"

  alb_arn       = module.app_alb.alb_arn
  associate_alb = true
}

Is this a known issue or something that has happened recently? I don't seem to have an answer for this. Here is the updated code I'm using:

module "alb_wafv2" {
  source  = "trussworks/wafv2/aws"
  version = "2.0"

  name  = "alb-web-acl"
  scope = "REGIONAL"

  alb_arn       = module.app_alb.alb_arn
  associate_alb = true
  managed_rules = [
    {
      "excluded_rules" : [],
      "name" : "AWSManagedRulesCommonRuleSet",
      "override_action" : "none",
      "priority" : 10
    },
    {
      "excluded_rules" : [],
      "name" : "AWSManagedRulesKnownBadInputsRuleSet",
      "override_action" : "none",
      "priority" : 30
    },
    {
      "excluded_rules" : [],
      "name" : "AWSManagedRulesSQLiRuleSet",
      "override_action" : "none",
      "priority" : 40
    },
    {
      "excluded_rules" : [],
      "name" : "AWSManagedRulesLinuxRuleSet",
      "override_action" : "none",
      "priority" : 50
    },
    {
      "excluded_rules" : [],
      "name" : "AWSManagedRulesUnixRuleSet",
      "override_action" : "none",
      "priority" : 60
    }
  ]
}

When expanding the plan for module.wafv2["allow"].aws_wafv2_web_acl.main to include new values learned so far during apply, provider

We were using a previous version of the module and want to upgrade to the latest. Using the latest aws provider terraform plan works, but terraform apply produces megabytes of error logs.

│ 
│ When expanding the plan for module.wafv2["allow"].aws_wafv2_web_acl.main to include new values learned so far during apply, provider
│ "registry.terraform.io/hashicorp/aws" produced an invalid new value for .rule: planned set element
│ cty.ObjectVal(map[string]cty.Value{"action":cty.ListValEmpty(cty.Object(map[string]cty.Type{"allow":cty.List(cty.Object(map[string]cty.Type{"custom_request_handling":cty.List(cty.Object(map[string]cty.Type{"insert_header":cty.Set(cty.Object(map[string]cty.Type{"name":cty.String,
│ "value":cty.String}))}))})),
│ "block":cty.List(cty.Object(map[string]cty.Type{"custom_response":cty.List(cty.Object(map[string]cty.Type{"custom_response_body_key":cty.String,
│ "response_code":cty.Number, "response_header":cty.Set(cty.Object(map[string]cty.Type{"name":cty.String, "value":cty.String}))}))})),
│ "captcha":cty.List(cty.Object(map[string]cty.Type{"custom_request_handling":cty.List(cty.Object(map[string]cty.Type{"insert_header":cty.Set(cty.Object(map[string]cty.Type{"name":cty.String,
│ "value":cty.String}))}))})),
│ "challenge":cty.List(cty.Object(map[string]cty.Type{"custom_request_handling":cty.List(cty.Object(map[string]cty.Type{"insert_header":cty.Set(cty.Object(map[string]cty.Type{"name":cty.String,
│ "value":cty.String}))}))})),
│ "count":cty.List(cty.Object(map[string]cty.Type{"custom_request_handling":cty.List(cty.Object(map[string]cty.Type{"insert_header":cty.Set(cty.Object(map[string]cty.Type{"name":cty.String,
│ "value":cty.String}))}))}))})),
│ "captcha_config":cty.ListValEmpty(cty.Object(map[string]cty.Type{"immunity_time_property":cty.List(cty.Object(map[string]cty.Type{"immunity_time":cty.Number}))})),
│ "name":cty.StringVal("AWSManagedRulesAmazonIpReputationList"),
│ "override_action":cty.ListVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{"count":cty.ListVal([]cty.Value{cty.EmptyObjectVal}),
│ "none":cty.ListValEmpty(cty.EmptyObject)})}), "priority":cty.NumberIntVal(2),
│ "rule_label":cty.SetValEmpty(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "statement":cty.ListVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{"and_statement":cty.ListValEmpty(cty.Object(map[string]cty.Type{"statement":cty.List(cty.Object(map[string]cty.Type{"and_statement":cty.List(cty.Object(map[string]cty.Type{"statement":cty.List(cty.Object(map[string]cty.Type{"and_statement":cty.List(cty.Object(map[string]cty.Type{"statement":cty.List(cty.Object(map[string]cty.Type{"byte_match_statement":cty.List(cty.Object(map[string]cty.Type{"field_to_match":cty.List(cty.Object(map[string]cty.Type{"all_query_arguments":cty.List(cty.EmptyObject),
│ "body":cty.List(cty.Object(map[string]cty.Type{"oversize_handling":cty.String})),
│ "cookies":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject),
│ "excluded_cookies":cty.List(cty.String), "included_cookies":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "headers":cty.List(cty.Object(map[string]cty.Type{"match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject),
│ "excluded_headers":cty.List(cty.String), "included_headers":cty.List(cty.String)})), "match_scope":cty.String, "oversize_handling":cty.String})),
│ "json_body":cty.List(cty.Object(map[string]cty.Type{"invalid_fallback_behavior":cty.String,
│ "match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "included_paths":cty.List(cty.String)})), "match_scope":cty.String,
│ "oversize_handling":cty.String})), "method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject),
│ "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})),
│ "positional_constraint":cty.String, "search_string":cty.String, "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number,
│ "type":cty.String}))})), "geo_match_statement":cty.List(cty.Object(map[string]cty.Type{"country_codes":cty.List(cty.String),
│ "forwarded_ip_config":cty.List(cty.Object(map[string]cty.Type{"fallback_behavior":cty.String, "header_name":cty.String}))})),
│ "ip_set_reference_statement":cty.List(cty.Object(map[string]cty.Type{"arn":cty.String,
│ "ip_set_forwarded_ip_config":cty.List(cty.Object(map[string]cty.Type{"fallback_behavior":cty.String, "header_name":cty.String, "position":cty.String}))})),
│ "label_match_statement":cty.List(cty.Object(map[string]cty.Type{"key":cty.String, "scope":cty.String})),
│ "regex_match_statement":cty.List(cty.Object(map[string]cty.Type{"field_to_match":cty.List(cty.Object(map[string]cty.Type{"all_query_arguments":cty.List(cty.EmptyObject),

[.... snip - megabytes of logs ...]

│ "match_pattern":cty.List(cty.Object(map[string]cty.Type{"all":cty.List(cty.EmptyObject), "included_paths":cty.List(cty.String)})), "match_scope":cty.String,
│ "oversize_handling":cty.String})), "method":cty.List(cty.EmptyObject), "query_string":cty.List(cty.EmptyObject),
│ "single_header":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})),
│ "single_query_argument":cty.List(cty.Object(map[string]cty.Type{"name":cty.String})), "uri_path":cty.List(cty.EmptyObject)})),
│ "text_transformation":cty.Set(cty.Object(map[string]cty.Type{"priority":cty.Number, "type":cty.String}))}))})}),
│ "visibility_config":cty.ListVal([]cty.Value{cty.ObjectVal(map[string]cty.Value{"cloudwatch_metrics_enabled":cty.True,
│ "metric_name":cty.StringVal("AWSManagedRulesCommonRuleSet"), "sampled_requests_enabled":cty.True})})}) does not correlate with any element in actual.
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.

Adding rule_action_override block to managed_group_rules block.

Is your feature request related to a problem? Please describe.
I was trying to import a WAF ACL which was created using terraform earlier but I was facing some issue with a rule from managed rule group so I had to override rule group action for that specific rule. When I tried to import that resource back it was creating new rule and removing overriden action that was done through console. Apparently rule_action_override block is missing terraform module which allows me the same functionality in terraform. Because of which I was facing the issue.

Describe the solution you'd like
There needs to be a dynamic block for rule_action_override in main.tf file just like it is there for excluded_rules and subsequent changes to variables.tf file.
Describe alternatives you've considered
I had to create a resource for the same as this functinality is missing.

Additional context
I tried to fork module's repo and made some changes to main.tf and variables.tf , and it worked as expected. Please try to consider my pull rquest and make these changes to module so I will be able to use it in my project.
PR URL : #111

Error while doing association with ALB

Hi, Thanks for great work.
Today, I tried to play with module and tried to use with ALB. The creation of WAFv2 with few rules got access and also creation of ALB also got succeeded.
But during the association of Wafv2 with ALB its starts complaining me the issue. I have used examples/alb/main.tf.
The error , I am getting is as below.

eval: *terraform.EvalSequence, err: InvalidParameter: 1 validation error(s) found.
 minimum field size of 20, AssociateWebACLInput.ResourceArn.

I am not able understand the exact error. Pls help.

Only log BLOCK requests

Is your feature request related to a problem? Please describe.
Enabling logging logs all requests

Describe the solution you'd like
Option to log only BLOCK requests

Describe alternatives you've considered
No other option beyond declaring the entire WAF resource myself

Additional context
N/A

NOT statements

Is there a way to incorporate NOT statements into the IP Sets Rule? We aim to add a condition to exclude specific IPs from being blocked while ensuring that the allowed IPs still adhere to the below conditions, such as rate limiting.

How to Use with Geographic Rules

Can this module be used to also restrict traffic to geographic regions such as countries? or deny based on country?

Can you give an example?

Support for Scope Down Statements

Is it possible to enhance the Rule Object to include a scope_down_statement so that particular requests can be excluded from the rule group.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#scope_down_statement
https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-scope-down-statements.html
{
"excluded_rules": [],
"name": "AWSManagedRulesCommonRuleSet",
"override_action": "none",
"priority": 10,
"scope_down_statement":
}

Unable to block all by default

It appears that

default_action {
  allow {}
}

is hardcoded. AWS doesn't allow me to create an ipset with 0.0.0.0/0. Is there a different way to accomplish this with this module?

AWS GovCloud now supports AWSManagedRulesAmazonIpReputationList

Greetings Trussels,

As of 12/2/2020, AWS GovCloud does not support the AWSManagedRulesAmazonIpReputationList managed rule set, which is enabled by default in this module. Until AWS supports that rule set, you will need to define your own managed_rules.

We experienced this same issue in GovCloud when previously trying AWSManagedRulesAmazonIpReputationList.

I tried AWSManagedRulesAmazonIpReputationList today (Feb 10 2021) in GovCloud (us-gov-west-1) and it appears that AWSManagedRulesAmazonIpReputationList is now supported. I can't find anything on AWS' docs to confirm, but I was able to successfully apply it via terraform on one of my projects.

Here is a screenshot of it in the AWS Console as well
Screen Shot 2021-02-10 at 6 52 05 PM

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.