Git Product home page Git Product logo

iamy's Introduction

IAMy

IAMy is a tool for dumping and loading your AWS IAM configuration into YAML files.

This allows you to use an Infrastructure as Code model to manage your IAM configuration. For example, you might use a github repo with a pull request model for changes to IAM config.

How it works

IAMy has two subcommands.

pull will sync IAM users, groups and policies from AWS to YAML files

push will sync IAM users, groups and policies from YAML files to AWS

For the push command, IAMy will output an execution plan as a series of aws cli commands which can be optionally executed. This turns out to be a very direct and understandable way to display the changes to be made, and means you can pick and choose exactly what commands get actioned.

Getting started

You can install IAMy on macOS with brew install iamy, or with the go toolchain go get -u github.com/99designs/iamy.

Because IAMy uses the aws cli tool, you'll want to install it first.

For configuration, IAMy uses the same AWS environment variables as the aws cli. You might find aws-vault an excellent complementary tool for managing AWS credentials.

Example Usage

$ iamy pull

$ find .
./myaccount-123456789/iam/user/joe.yml

$ mkdir -p myaccount-123456789/iam/user/foo

$ touch myaccount-123456789/iam/user/foo/bar.baz

$ cat << EOD > myaccount-123456789/iam/user/billy.blogs
Policies:
- arn:aws:iam::aws:policy/ReadOnly
EOD

$ iamy push
Commands to push changes to AWS:
        aws iam create-user --path /foo --user-name bar.baz
        aws iam create-user --user-name billy.blogs
        aws iam attach-user-policy --user-name billy.blogs --policy-arn arn:aws:iam::aws:policy/ReadOnly

Exec all aws commands? (y/N) y

> aws iam create-user --path /foo --user-name bar.baz
> aws iam create-user --user-name billy.blogs
> aws iam attach-user-policy --user-name billy.blogs --policy-arn arn:aws:iam::aws:policy/ReadOnly

Accurate cloudformation matching

By default, iamy will use a simple heuristic (does it end with an ID, eg -ABCDEF1234) to determine if a given resource is managed by cloudformation.

This behaviour is good enough for some cases, but if you want slower but more accurate matching pass --accurate-cfn to enumerate all cloudformation stacks and resources to determine exactly which resources are managed.

Inspiration and similar tools

iamy's People

Contributors

andrewjhumphrey avatar dctrwatson avatar elyscape avatar envatopoho avatar jacobbednarz avatar lox avatar mrafter avatar mtibben avatar pda avatar skuenzli avatar tchia04 avatar vektah 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  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

iamy's Issues

Project status

Is this project still safe to use?
Will it work with AWS cli v2?

It can not be installed using go install:

$ go install github.com/99designs/iamy@latest
go: finding module for package github.com/fatih/color
go: finding module for package github.com/ghodss/yaml
go: finding module for package github.com/aws/aws-sdk-go/aws/awserr
go: finding module for package github.com/aws/aws-sdk-go/service/sts
go: finding module for package github.com/aws/aws-sdk-go/aws
go: finding module for package github.com/aws/aws-sdk-go/service/iam
go: finding module for package github.com/aws/aws-sdk-go/aws/session
go: finding module for package github.com/aws/aws-sdk-go/service/iam/iamiface
go: finding module for package github.com/aws/aws-sdk-go/service/ec2
go: finding module for package github.com/aws/aws-sdk-go/service/s3/s3iface
go: finding module for package github.com/aws/aws-sdk-go/service/s3
go: finding module for package gopkg.in/alecthomas/kingpin.v2
go: finding module for package github.com/pkg/errors
go: found github.com/fatih/color in github.com/fatih/color v1.16.0
go: found gopkg.in/alecthomas/kingpin.v2 in gopkg.in/alecthomas/kingpin.v2 v2.4.0
go: found github.com/aws/aws-sdk-go/aws in github.com/aws/aws-sdk-go v1.51.3
go: found github.com/aws/aws-sdk-go/aws/awserr in github.com/aws/aws-sdk-go v1.51.3
go: found github.com/aws/aws-sdk-go/aws/session in github.com/aws/aws-sdk-go v1.51.3
go: found github.com/aws/aws-sdk-go/service/ec2 in github.com/aws/aws-sdk-go v1.51.3
go: found github.com/aws/aws-sdk-go/service/iam in github.com/aws/aws-sdk-go v1.51.3
go: found github.com/aws/aws-sdk-go/service/iam/iamiface in github.com/aws/aws-sdk-go v1.51.3
go: found github.com/aws/aws-sdk-go/service/s3 in github.com/aws/aws-sdk-go v1.51.3
go: found github.com/aws/aws-sdk-go/service/s3/s3iface in github.com/aws/aws-sdk-go v1.51.3
go: found github.com/aws/aws-sdk-go/service/sts in github.com/aws/aws-sdk-go v1.51.3
go: found github.com/ghodss/yaml in github.com/ghodss/yaml v1.0.0
go: found github.com/pkg/errors in github.com/pkg/errors v0.9.1
go: github.com/99designs/iamy imports
	gopkg.in/alecthomas/kingpin.v2: gopkg.in/alecthomas/[email protected]: parsing go.mod:
	module declares its path as: github.com/alecthomas/kingpin/v2
	       but was required as: gopkg.in/alecthomas/kingpin.v2

Support for AWS service-linked roles

Roles with a prefix beginning with /aws-service-role/ and a name beginning with AWSServiceRoleFor have special handling by AWS and must be created as service-linked roles. Currently, it tries to define them as regular roles, leading to failure:

myhost:iamy-policies elyscape$ cat REDACTED/iam/role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS.yaml
AssumeRolePolicyDocument:
  Statement:
  - Action: sts:AssumeRole
    Effect: Allow
    Principal:
      Service: ecs.amazonaws.com
  Version: 2012-10-17
Description: Allows ECS to create and manage AWS resources on your behalf.
Policies:
- arn:aws:iam::aws:policy/aws-service-role/AmazonECSServiceRolePolicy
myhost:iamy-policies elyscape$ iamy push
Commands to push changes to AWS:

      aws iam create-role --role-name AWSServiceRoleForECS --path /aws-service-role/ecs.amazonaws.com/ --description 'Allows ECS to create and manage AWS resources on your behalf.' --assume-role-policy-document '{
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs.amazonaws.com"
      }
    }
  ],
  "Version": "2012-10-17"
}'
      aws iam attach-role-policy --role-name AWSServiceRoleForECS --policy-arn arn:aws:iam::aws:policy/aws-service-role/AmazonECSServiceRolePolicy

Run 2 aws commands (0 destructive)? (y/N) y

> aws iam create-role --role-name AWSServiceRoleForECS --path /aws-service-role/ecs.amazonaws.com/ --description 'Allows ECS to create and manage AWS resources on your behalf.' --assume-role-policy-document '{
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs.amazonaws.com"
      }
    }
  ],
  "Version": "2012-10-17"
}'

An error occurred (InvalidInput) when calling the CreateRole operation: Path prefix '/aws-service-role/' can only be used for AWS Service linked Roles
exit status 255

The role definition was generated by running:

aws iam create-service-linked-role --aws-service-name ecs.amazonaws.com --description 'Allows ECS to create and manage AWS resources on your behalf.'

and then running iamy pull.

Managed policy limits

We've recently started managing some policies with iamy. Unfortunately, customer-managed policies come with a pretty low service limit of 5:

$iamy push -d .
...
An error occurred (LimitExceeded) when calling the CreatePolicyVersion operation: A managed policy can have up to 5 versions. Before you create a new version, you must delete an existing version.

It may be possible to have this limit raised (although the IAM docs don't call it out specifically as one that can be raised).

In any case, I wonder if iamy, being a tool that manages managed policies, should have some smarts to handle this case. If so, the path of least resistance may be to first check the number of versions, and if 5 then delete the oldest version, before adding the new version.

Thoughts?

Terminology: dump and load are unclear

It's very unclear what dump and load mean. I gather dump fetches the current data from upstream and writes it to local files, and load reads data from local files and figures out the commands to push that to upstream.

Instead of dump, how about pull, fetch or download.
Instead of load, how about push, publish or upload.

(I noticed load generates aws commands but doesn't run them. That might just mean the name should be generate-push-commands.)

Error fetching bucket that does not exist

The S3 ListBuckets API call is eventually consistent. So it's possible an S3 bucket returned does not actually exist. this results in an error like:

Error fetching S3 data: Error listing buckets: Error while getting details for S3 bucket non-existant-bucket: NoSuchBucket: The specified bucket does not exist
	status code: 404, ...

iamy should ignore such errors.

Release new version

The currently-released version, 2.2.0, adds support for instance profiles. Unfortunately, as documented in #47, this functionality is broken. #48 fixed it, but there hasn't been a release since it was merged. Please make a 2.2.1 release with the fix.

BucketRegionError thrown when retreiving GetBucketPolicyDoc if account has buckets in two different regions

Most of our buckets live in Sydney, but we have one that lives in the US. When running iamy pull I get the following error:

Error fetching S3 data: Error listing buckets: Error while getting details for S3 bucket [redacted]: GetBucketPolicyDoc for [redacted]: BucketRegionError: incorrect region, the bucket is not in 'ap-southeast-2' region

It looks like the Go SDK can't handle multiple regions for S3 buckets.

Unreliable detection of CloudFormation-managed resources

IAMy attempts to ignore resources that are part of CloudFormation stacks; they're likely to come and go, and be version controlled elsewhere (in the CloudFormation template). It does this by comparing the resources name against the regular expression -[A-Z0-9]{10,20}$, which matches CloudFormation-generated resource names. This is not ideal, because;

  • The pattern may match resources not managed by CloudFormation.
  • The pattern will not match CloudFormation resources where a name was specified, e.g. RoleName for an AWS::IAM::Role.

Unfortunately I can't see a simple way to improve this (which I imagine is how it came to be done this way). I imagine the only reliable way would be to enumerate all CloudFormation stacks first and keep a list of resource ARNs, and use that list as a filter in IAMy.

Ignore aws-service-role?

I am seeing a role synced down locally for one of my accounts:

<account>/iam/role/aws-service-role/spot.amazonaws.com/AWSServiceRoleForEC2Spot.yaml

I suspect it's an AWS thing? Should this be ignored?

Dry-run

I'd love to be able to put iamy push into my CI system (so I could see what would be applied), but without actually applying it.

I've tried passing a falsy value into STDIN (e.g. false | iamy ... and echo n | iamy ...) with no luck. A --dry-run flag would be ace.

Detach/Attach custom policy to IAM user

I have noticed the following bug:

I've defined an IAM user which has attached to it a custom policy. Everytime I run the push I got the following result:

aws iam detach-user-policy --user-name foo --policy-arn arn:aws:iam::xxxxxxxxxxxxx:policy/my-custom-policy
aws iam attach-user-policy --user-name foo --policy-arn arn:aws:iam::xxxxxxxxxxxxx:policy/my-custom-policy

so basically a diff is detected even though there is no real diff

IAMY doesn't resolve dependancies before applying

Description: When removing and detaching a policy, iamy tries to delete it first. This fails as the policy is still attached to a role.
Version: 2.0.0-beta2
Steps to reproduce:

  • Create a policy and attach it to that role
  • Run iamy push
  • Delete the policy and detach it from that role
  • Run iamy push

Outcome:

An error occurred (DeleteConflict) when calling the DeletePolicy operation: Cannot delete a policy attached to entities.
exit status 255

Expected outcome:
iamy detaches the policy from the role before deleting it.

IAMy attempts to delete instance profiles without removing all roles first

When iamy push would result in an instance profile being deleted, IAMy attempts to delete the instance profile directly, without removing the roles from it. This results in failure:

Commands to push changes to AWS:

      aws iam delete-instance-profile --instance-profile-name delete_this_role

Run 1 aws command (1 destructive)? (y/N) 
> y
aws iam delete-instance-profile --instance-profile-name delete_this_role

An error occurred (DeleteConflict) when calling the DeleteInstanceProfile operation: Cannot delete entity, must remove roles from instance profile first.

Take a backup of resources before deleting them

Sometimes we accidentally delete policies/roles when doing a push. It would be nice if IAMy could, optionally, take a backup of them before deleting them and drop them in a seperate directory (outside the normal account directory structure) in case this was not what was intended.

Homebrew formula?

I'd be keen to get this into homebrew, might submit a PR tomorrow if nobody has any objections.

Support for Policy description

iamy doesn't seem to support descriptions on IAM policies, while AWS Console and AWS CLI do:

Tool
AWS console Policy Name Description Policy Document
AWS CLI --policy-name --description --policy-document
iamy File name missing File content

Perhaps it could be a top-level Description key in YAML which iamy pulls out into the --description CLI arg?

iamy sporadically fail with errors.

Iamy sporadically fail with error:

Error fetching S3 data: Error listing buckets: Error while getting details for S3 bucket bucketname: RequestError: send request failed
caused by: Get https://s3.us-west-2.amazonaws.com/bucketname?location=: dial tcp: lookup s3.us-west-2.amazonaws.com: no such host286 <nil>

It failing all the time with errors on different bucket.
looks like it is throttling from amazon side.

Iamy version v2.3.2

Feature request: provide a diff of changed resources

A common use case we have for iamy is to add a user to the assume-role-policy-document for some role. When there are already a number of users in such a list, it can be tricky to spot the change shown when iamy push shows the command it's going to run.

It would be super handy if there was an (optional?) way to show a diff view of the change between what's live and what's about to be pushed, so you could easily see (for example) the one user being added to the policy. This would no doubt be helpful on selected other resources too.

Will try and come up with some scrubbed example output here shortly.

GCP equivalent

Does anyone know of a similar tool like this for GCP?

Proposal: .iamy-version file

We've had a few issues where people have gotten stuck/confused because the version of iamy they're running is newer/older than the version last used in that repository.

I'd like to add an .iamy-version file to be written to working directory that is in part inspired by Ruby bundler's version checking.

Behaviour:

  • if it doesn't exist, it's created as .iamy-version with the current output of iamy --version and an INFO message is printed
  • if it does exist and your version is newer than what's in .iamy-version, the file is overwritten and an INFO message is printed
  • if it does exist and your version is the same, nothing happens
  • if it does exist and your version is older by minor or patch version, a WARN message is printed
  • if it does exist and your version is older by major version, an ERROR message is printed and execution stops

Additional AWS authorization mechanisms

From https://cloudonaut.io/aws-security-primer/

Besides IAM Policies, some services use additional authorization mechanism. The services with their own authorization mechanism are:

  • SNS and SQS: A Topic Policy or Queue Policy can open a topic/queue to things like IAM User, IAM Role, AWS Account, or just all of us. This can be handy, but you should think twice before doing so. Most likely, you can use the assume role approach to achieve the same!
  • Glacier: Glacier comes with two types of policies, one to control access, and the other to control modification of archives. The latter is important if you have to enforce that data can not be changed for legal reasons.
  • IoT: As mentioned, IoT Things can authenticate, and the Policy determines what they can do in your AWS account.
  • Lambda: A Lambda Function can be opened for invocation by a Permission. This is needed if you want a “Cron” to trigger your Lambda because this “Cron” is AWS. So AWS needs permissions to invoke your function. Most likely, you can use the assume role approach to achieve the same!
  • S3: S3 is the king of alternative ways for authorization.
    • You can set ACLs on the bucket and object level to give read/write permissions. I recommend no using them. There is no simple way to change all ACLs on the object level. And it is very hard to reason if every object can have different permissions.
    • You can also use a Bucket Policy to give read/write permissions to your bucket/objects. This makes sense if your bucket is public and you ant to give read access to the world.
    • You can also generate pre-signed URLs to give temporary permissions to read or upload objects. This makes sense if you want users to directly upload files from their browser.
  • KMS: Key Policies are the primary way to control access to customer master keys (CMKs) in KMS. On top of that, you can use IAM policies to authorize. The second way to control access are Grants. With a Grant, you can allow another AWS principal (e.g. an AWS account) to use a CMK with some restrictions. You could also implement this with the Key policy, but grants are more flexible to control.

The only additional authorization mechanism iamy supports at the moment is S3 bucket policies. In the interests of making this more of an umbrella tool for AWS authorization, should we support more of these mechanisms?

collect ECR repository policies too

ECR repositories can have policies too. aws ecr get-repository-policy will retrieve it. iamy should support them similar to the s3 policies.

MalformedPolicyDocument: The policy failed legacy parsing

Ran into a strange issue with this group policy:

> aws iam put-group-policy --group-name AdministratorsWithMFA --policy-name AllowAssumingBastionRole --policy-document '{
  "Statement": {
    "Action": "sts:AssumeRole",
    "Effect": "Allow",
    "Resource": "arn:aws:iam::xxx:role/bastion"
  },
  "Version": "2012-10-17"
}'

An error occurred (MalformedPolicyDocument) when calling the PutGroupPolicy operation: The policy failed legacy parsing
exit status 255

Looks like the Version key needs to be the first thing. Seems horrible. This works:

{
  "Version": "2012-10-17",
  "Statement": {
    "Action": "sts:AssumeRole",
    "Effect": "Allow",
    "Resource": "arn:aws:iam::xxx:role/bastion"
  }
}

Error fetching S3 data

Hi there,

I upgraded to 2.0 and couldn't do iamy pull anymore. Got error:

iamy pull
Error fetching S3 data: Error listing buckets: Error while calling ListBuckets: MissingRegion: could not find region configuration130 <nil>

I know it's beta ;) I'm just keen to try the S3 bucket policy document.

Issues with aws-service-roles after upgrading to 2.3.0

#53 makes a change to completely ignore aws-service-roles. This raises an issue when you migrate to 2.3, it tries to create aws-service-roles as they are not "synced".

The fix I've implemented is to delete aws-service-role/* from our repo. I've documented this now in the releases page but we should do anything further?

cc @jacobbednarz

Note

You should remove all roles under iam/roles/aws-service-role/ as these are no longer managed by iamy

Unrelated changes are made during push

I made a change to a role, and in addition to the desired change, iamy also output the following change:

        aws iam update-assume-role-policy --role-name cloudwatch-alarm-deleter-role --policy-document '{
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "lambda.amazonaws.com",
                  "sns.amazonaws.com"
                ]
              },
              "Sid": ""
            }
          ],
          "Version": "2012-10-17"
        }'

This change is completely unrelated to the previous change. When allow iamy to apply the change, it applies cleanly. When I do a subsequent pull, I see that the order of the two entries in the Service array above has been reversed:

$ git diff iamy/.../role/cloudwatch-alarm-deleter-role.yaml
--- a/iamy/.../role/cloudwatch-alarm-deleter-role.yaml
+++ b/iamy/./role/cloudwatch-alarm-deleter-role.yaml
@@ -4,8 +4,8 @@ AssumeRolePolicyDocument:
     Effect: Allow
     Principal:
       Service:
-      - lambda.amazonaws.com
       - sns.amazonaws.com
+      - lambda.amazonaws.com
     Sid: ""
   Version: 2012-10-17
 InlinePolicies:

This behavior is repeatable, and although it's not always the above role that gets updated, it is always just a re-order of array entries.

I've tried both v1.0.2, and the dev version that go get gives me; both exhibit the same behavior.

Great tool by the way! Makes IAM management so much easier.

Cheers,
Ross

Support AWS CLI --profile

To the best of my knowledge, it's currently impossible to identify which profile stored in ~/.aws/credentials to use with iamy.

I'll recommend to include profile as pull and push sub parameter to support AWS CLI --profile.

Non-interactive CLI

In the case I need to run iamy push in a non-interactive env like for example CircleCI how should I reply to the question? I haven't found any non-interactive mode.

RFC: Should iamy manage S3 bucket policies

Should iamy also manage S3 bucket policies? Is that in-scope for a tool like this?

I'd be keen to hear the thoughts of people using this tool /cc @lox @pda @simpsora @SomeoneWeird @joho

We typically use roles to manage cross-account access, however it's sometimes convenient to use S3 bucket policies to allow a user in a different account direct access to a bucket. Because you are granting access to users, it works in a complementary way with an IAM user policy.

If iamy were to manage bucket policies, it also raises the question whether we should manage bucket ACLs also? I lean towards no - bucket policies can achieve everything bucket ACLs can, and ACLs apply to both buckets as well as objects in the bucket - it seems out of scope to manage individual resources.

If we were to implement management of s3 bucket policies, where should we represent these policies in the filesystem?

Option 1: Prefix using the service name iam or s3 - would require existing filesystem to move around slightly e.g.

{account-id}/iam/{user,group,role,policy}/{name}
{account-id}/s3/{bucket-name}

Option 2: Don't move anything e.g.

{account-id}/{user,group,role,policy,s3}/{name}

Option 3: Follow the ARN format ordering e.g.

iam/{account-id}/{user,group,role,policy}/{name}
s3/{account-id}/{bucket-name}

I'm leaning towards Option 2.

References:

Following the example usage of "touch some_user" causes syntax error

~/iamy/tchia04-99999999999/iam/user $ touch dummy.yaml
~/iamy/tchia04-99999999999/iam/user $ iamy
~/iamy/tchia04-99999999999/iam/user $ cd ../../
~/iamy/tchia04-99999999999 $ cd ..
~/iamy $ iamy push
Commands to push changes to AWS:

  aws iam create-user --user-name dummy --path / --tags

Run 1 aws commands (0 destructive)? (y/N) y

aws iam create-user --user-name dummy --path / --tags

Error parsing parameter '--tags': Expected: '=', received: 'EOF' for input:

^
exit status 255

It seems the aws cli command generated included the extra --tags which the example usage didn't show.

If I deleted the "--tags" then the aws cli command works fine.

~/iamy $ aws iam create-user --user-name dummy --path /
{
"User": {
"UserName": "dummy",
"Path": "/",
"CreateDate": "2019-03-26T16:00:03Z",
"UserId": "AIDAI5D47SCFWEVSRAFC4",
"Arn": "arn:aws:iam::99999999999:user/dummy"
}
}
~/iamy $

$ aws --version
aws-cli/1.16.96 Python/2.7.10 Darwin/18.2.0 botocore/1.12.86
~/iamy $

Error fetching S3 data

Hi,

I'm using version v2.0.0-beta2 (love the list normalisation change btw) and have run into an issue when pulling down S3 data.

$ iamy pull
Error fetching S3 data: Error listing buckets: Error while calling ListBuckets: MissingRegion: could not find region configuration130 <nil>

Not sure where configuration130 is coming from. Any ideas on why it's getting an incorrect region?

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.