From 8fb6a9f1c77f8ea4d510a61df20b002a5be5448d Mon Sep 17 00:00:00 2001 From: kbehrman Date: Sat, 6 Jul 2019 16:16:52 -0700 Subject: [PATCH 01/56] spelling --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e1eb11edb4..a5d56605de 100755 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 1. Fork this project by pressing the fork buton 2. Locally clone your Forked version. You can now begin modifying it. -## Containarizing and Running Locally +## Containerizing and Running Locally The supplied flask app is a very simple api with three endpoints. GET '/': This is a simple health check, which returns the response 'Healthy'. POST '/auth': This takes a email and password as json arguments and returns a jwt token base on a custom secret. From 322c85271acbcc5284c3466f961d658251d0e2ec Mon Sep 17 00:00:00 2001 From: Stephen Welch Date: Mon, 15 Jul 2019 14:52:03 -0700 Subject: [PATCH 02/56] Update README.md --- README.md | 77 +++++++++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index a5d56605de..d320a82240 100755 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ GET '/contents': This requires a valid jwt token, and returns the un-encrpyted c ### Run the Api using Flask Server 1. Install python dependencies. These dependencies are kept in a requirements.txt file. To install them, use pip: - ```bash +```bash pip install -r requirements.txt - ``` +``` 1. Setting up environment @@ -27,30 +27,30 @@ pip install -r requirements.txt **LOG_LEVEL** - The level of logging. Will default to 'INFO', but when debugging an app locally, you may want to set it to 'DEBUG' - ```bash +```bash export JWT_SECRET=myjwtsecret export LOG_LEVEL=DEBUG ``` 3. Run the app using the Flask server, from the flask-app directory, run: - ```bash +```bash python app/main.py ``` To try the api endpoints, open a new shell and run, replacing '\' and '\' with and any values: - ```bash +```bash export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST localhost:80/auth | jq -r '.token'` ``` This calls the endpoint 'localhost:80/auth' with the '{"email":"","password":""}' as the message body. The return value is a jwt token based on the secret you supplied. We are assigning that secret to the environment variable 'TOKEN'. To see the jwt token, run: - ```bash +```bash echo $TOKEN ``` To call the 'contents' endpoint, which decrpyts the token and returns it content, run: - ```bash +```bash curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TOKEN}" | jq . ``` You should see the email that you passed in as one of the values. @@ -67,35 +67,35 @@ curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TO gunicorn should be run with the arguments: - ``` +```bash gunicorn -b :8080 main:APP ``` 3. Create a file named 'env_file' and use it to set the environment variables which will be run locally in your container. Here we do not need the export command, just an equals sign: - +``` \=\ - -4. Build a Local Docker Image - To build a Docker image run: ``` + +4. Build a Local Docker Image. To build a Docker image run: +```bash docker build -t jwt-api-test . ``` 5. Run the image locally, using the 'gunicorn' server: - ``` +```bash docker run --env-file=env_file -p 80:8080 jwt-api-test ``` - To use the endpoints use the same curl commands as before: + To use the endpoints use the same curl commands as before: - ```bash +```bash export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST localhost:80/auth | jq -r '.token'` ``` - ```bash +```bash curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TOKEN}" | jq . - ``` +``` ## Deployment to Kubernetes using CodePipeline and CodeBuild @@ -103,42 +103,41 @@ curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TO 1. Install aws cli - ```bash +```bash pip install awscli --upgrade --user ``` Note: If you are using a Python virtual environment, the command will be: - ```bash +```bash pip install awscli --upgrade ``` -2. -[Generate a aws access key id and secret key](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) +2. [Generate a aws access key id and secret key](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) 3. Setup your environment to use these keys: If you not already have a aws 'credentials' file setup, run: - ```bash +```bash aws configure ``` And use the credentials you generated in step 2. Your aws commandline tools will now use these credentials. 4. Install the 'eksctl' tool. - The 'eksctl' tool allow interaction wth a EKS cluster from the command line. To install, follow the [directions for your platform](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html) + The 'eksctl' tool allow interaction wth a EKS cluster from the command line. To install, follow the [directions for your platform](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html). 5. Create a EKS cluster - ```bash -eksctl create cluster --name simple-jwt-api --version 1.12 --nodegroup-name standard-workers --nodes 3 --nodes-min 1 --nodes-max 4 --node-ami auto +```bash +eksctl create cluster --name simple-jwt-api --version 1.12 --nodegroup-name standard-workers --nodes 3 --nodes-min 1 --nodes-max 4 --node-ami auto ``` This will take some time to do. Progress can be checked by visiting the aws console and selecting EKS from the services. 6. Check the cluster is ready: - ```bash +```bash kubectl get nodes ``` @@ -150,7 +149,7 @@ You will now create a pipeline which watches your Github. When changes are check 1. Create an IAM role that CodeBuild can use to interact with EKS: - ```bash +```bash ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }" echo '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:Describe*", "ssm:GetParameters" ], "Resource": "*" } ] }' > /tmp/iam-role-policy @@ -163,7 +162,7 @@ aws iam put-role-policy --role-name UdacityFlaskDeployCBKubectlRole --policy-nam 1. Grant the role access to the cluster. The 'aws-auth ConfigMap' is used to grant role based access control to your cluster. - ``` +```bash ROLE=" - rolearn: arn:aws:iam::$ACCOUNT_ID:role/UdacityFlaskDeployCBKubectlRole\n username: build\n groups:\n - system:masters" kubectl get -n kube-system configmap/aws-auth -o yaml | awk "/mapRoles: \|/{print;print \"$ROLE\";next}1" > /tmp/aws-auth-patch.yml kubectl patch configmap/aws-auth -n kube-system --patch "$(cat /tmp/aws-auth-patch.yml)" @@ -175,7 +174,7 @@ This token should be saved somewhere that is secure. 1. The file *buildspec.yml* instructs CodeBuild. We need a way to pass your jwt secret to the app in kubernetes securly. You will be using AWS parameter-store to do this. First add the following to your buildspec.yml file: - ```yaml +```yaml env: parameter-store: JWT_SECRET: JWT_SECRET @@ -185,7 +184,7 @@ env: 1. Put secret into AWS Parameter Store - ``` +```bash aws ssm put-parameter --name JWT_SECRET --value "YourJWTSecret" --type SecureString ``` @@ -200,27 +199,27 @@ aws ssm put-parameter --name JWT_SECRET --value "YourJWTSecret" --type SecureStr Save this file. 1. Create a stack for CodePipeline - - Go the the [CloudFormation service](https://us-east-2.console.aws.amazon.com/cloudformation/) in the aws console. - - Press the 'Create Stack' button. - - Choose the 'Upload template to S3' option and upload the template file 'ci-cd-codepipeline.cfn.yml' - - Press 'Next'. Give the stack a name, fill in your GitHub login and the Github access token generated in step 9. - - Confirm the cluster name matches your cluster, the 'kubectl IAM role' matches the role you created above, and the repository matches the name of your forked repo. - - Create the stack. + - Go the the [CloudFormation service](https://us-east-2.console.aws.amazon.com/cloudformation/) in the aws console. + - Press the 'Create Stack' button. + - Choose the 'Upload template to S3' option and upload the template file 'ci-cd-codepipeline.cfn.yml' + - Press 'Next'. Give the stack a name, fill in your GitHub login and the Github access token generated in step 9. + - Confirm the cluster name matches your cluster, the 'kubectl IAM role' matches the role you created above, and the repository matches the name of your forked repo. + - Create the stack. - You can check it's status in the [CloudFormation console](https://us-east-2.console.aws.amazon.com/cloudformation/). + You can check it's status in the [CloudFormation console](https://us-east-2.console.aws.amazon.com/cloudformation/). 1. Check the pipeline works. Once the stack is successfully created, commit a change to the master branch of your github repo. Then, in the aws console go to the [CodePipeline UI](https://us-east-2.console.aws.amazon.com/codesuite/codepipeline). You should see that the build is running. 16. To test your api endpoints, get the external ip for your service: - ``` +``` bash kubectl get services simple-jwt-api -o wide ``` Now use the external ip url to test the app: - ``` +```bash export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST :80/auth | jq -r '.token'` curl --request GET ':80/contents' -H "Authorization: Bearer ${TOKEN}" | jq ``` From 54b3d479c071e4267df097737ad93fd91c7dc7f3 Mon Sep 17 00:00:00 2001 From: Stephen Welch Date: Mon, 15 Jul 2019 15:06:00 -0700 Subject: [PATCH 03/56] Update README.md --- README.md | 252 ++++++++++++++++++++++++++---------------------------- 1 file changed, 121 insertions(+), 131 deletions(-) diff --git a/README.md b/README.md index d320a82240..b296090729 100755 --- a/README.md +++ b/README.md @@ -11,49 +11,45 @@ POST '/auth': This takes a email and password as json arguments and returns a j GET '/contents': This requires a valid jwt token, and returns the un-encrpyted contents of that token. ### Run the Api using Flask Server -1. Install python dependencies. These dependencies are kept in a requirements.txt file. To install them, use pip: +1. Install python dependencies. These dependencies are kept in a requirements.txt file. To install them, use pip: + ```bash + pip install -r requirements.txt + ``` +2. Set up the environment. The following environment variable is required: -```bash -pip install -r requirements.txt -``` + **JWT_SECRET** - The secret used to make the JWT token, for the purpose of this course it can be any string. -1. Setting up environment + The following environment variable is optional: - The following environment variable is required: + **LOG_LEVEL** - The level of logging. Will default to 'INFO', but when debugging an app locally, you may want to set it to 'DEBUG' - **JWT_SECRET** - The secret used to make the JWT token, for the purpose of this course it can be any string. - - The following environment variable is optional: - - **LOG_LEVEL** - The level of logging. Will default to 'INFO', but when debugging an app locally, you may want to set it to 'DEBUG' - -```bash -export JWT_SECRET=myjwtsecret -export LOG_LEVEL=DEBUG -``` + ```bash + export JWT_SECRET=myjwtsecret + export LOG_LEVEL=DEBUG + ``` 3. Run the app using the Flask server, from the flask-app directory, run: -```bash -python app/main.py -``` + ```bash + python app/main.py + ``` - To try the api endpoints, open a new shell and run, replacing '\' and '\' with and any values: + To try the api endpoints, open a new shell and run, replacing '\' and '\' with and any values: -```bash -export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST localhost:80/auth | jq -r '.token'` -``` + ```bash + export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST localhost:80/auth | jq -r '.token'` + ``` - This calls the endpoint 'localhost:80/auth' with the '{"email":"","password":""}' as the message body. The return value is a jwt token based on the secret you supplied. We are assigning that secret to the environment variable 'TOKEN'. To see the jwt token, run: + This calls the endpoint 'localhost:80/auth' with the '{"email":"","password":""}' as the message body. The return value is a jwt token based on the secret you supplied. We are assigning that secret to the environment variable 'TOKEN'. To see the jwt token, run: -```bash -echo $TOKEN -``` - To call the 'contents' endpoint, which decrpyts the token and returns it content, run: + ```bash + echo $TOKEN + ``` + To call the 'contents' endpoint, which decrpyts the token and returns it content, run: -```bash -curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TOKEN}" | jq . -``` - You should see the email that you passed in as one of the values. + ```bash + curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TOKEN}" | jq . + ``` + You should see the email that you passed in as one of the values. ### Dockerize and Run Locally @@ -65,37 +61,37 @@ curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TO - Install needed python requirements - Define an entrypoint which will run the main app using the gunicorn WSGI server - gunicorn should be run with the arguments: + gunicorn should be run with the arguments: -```bash -gunicorn -b :8080 main:APP -``` + ```bash + gunicorn -b :8080 main:APP + ``` 3. Create a file named 'env_file' and use it to set the environment variables which will be run locally in your container. Here we do not need the export command, just an equals sign: -``` - \=\ -``` + ``` + \=\ + ``` 4. Build a Local Docker Image. To build a Docker image run: -```bash -docker build -t jwt-api-test . -``` + ```bash + docker build -t jwt-api-test . + ``` 5. Run the image locally, using the 'gunicorn' server: -```bash -docker run --env-file=env_file -p 80:8080 jwt-api-test -``` + ```bash + docker run --env-file=env_file -p 80:8080 jwt-api-test + ``` - To use the endpoints use the same curl commands as before: + To use the endpoints use the same curl commands as before: -```bash -export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST localhost:80/auth | jq -r '.token'` -``` -```bash -curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TOKEN}" | jq . -``` + ```bash + export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST localhost:80/auth | jq -r '.token'` + ``` + ```bash + curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TOKEN}" | jq . + ``` ## Deployment to Kubernetes using CodePipeline and CodeBuild @@ -103,45 +99,43 @@ curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TO 1. Install aws cli -```bash -pip install awscli --upgrade --user -``` + ```bash + pip install awscli --upgrade --user + ``` - Note: If you are using a Python virtual environment, the command will be: + Note: If you are using a Python virtual environment, the command will be: -```bash -pip install awscli --upgrade -``` + ```bash + pip install awscli --upgrade + ``` 2. [Generate a aws access key id and secret key](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) 3. Setup your environment to use these keys: - If you not already have a aws 'credentials' file setup, run: -```bash -aws configure -``` -And use the credentials you generated in step 2. Your aws commandline tools will now use these credentials. +If you not already have a aws 'credentials' file setup, run: -4. Install the 'eksctl' tool. - - The 'eksctl' tool allow interaction wth a EKS cluster from the command line. To install, follow the [directions for your platform](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html). + ```bash + aws configure + ``` + and use the credentials you generated in step 2. Your aws commandline tools will now use these credentials. -5. Create a EKS cluster - -```bash -eksctl create cluster --name simple-jwt-api --version 1.12 --nodegroup-name standard-workers --nodes 3 --nodes-min 1 --nodes-max 4 --node-ami auto -``` +4. Install the 'eksctl' tool. The 'eksctl' tool allow interaction wth a EKS cluster from the command line. To install, follow the [directions for your platform](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html). - This will take some time to do. Progress can be checked by visiting the aws console and selecting EKS from the services. +5. Create an EKS cluster + + ```bash + eksctl create cluster --name simple-jwt-api --version 1.12 --nodegroup-name standard-workers --nodes 3 --nodes-min 1 --nodes-max 4 --node-ami auto + ``` + This will take some time to do. Progress can be checked by visiting the aws console and selecting EKS from the services. 6. Check the cluster is ready: -```bash -kubectl get nodes -``` + ```bash + kubectl get nodes + ``` - If the nodes are up and healthy, the cluster should be ready. + If the nodes are up and healthy, the cluster should be ready. ### Create Pipeline You will now create a pipeline which watches your Github. When changes are checked in, it will build a new image and deploy it to your cluster. @@ -149,46 +143,44 @@ You will now create a pipeline which watches your Github. When changes are check 1. Create an IAM role that CodeBuild can use to interact with EKS: -```bash -ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) -TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }" -echo '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:Describe*", "ssm:GetParameters" ], "Resource": "*" } ] }' > /tmp/iam-role-policy -aws iam create-role --role-name UdacityFlaskDeployCBKubectlRole --assume-role-policy-document "$TRUST" --output text --query 'Role.Arn' -aws iam put-role-policy --role-name UdacityFlaskDeployCBKubectlRole --policy-name eks-describe --policy-document file:///tmp/iam-role-policy -``` + ```bash + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }" + echo '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:Describe*", "ssm:GetParameters" ], "Resource": "*" } ] }' > /tmp/iam-role-policy + aws iam create-role --role-name UdacityFlaskDeployCBKubectlRole --assume-role-policy-document "$TRUST" --output text --query 'Role.Arn' + aws iam put-role-policy --role-name UdacityFlaskDeployCBKubectlRole --policy-name eks-describe --policy-document file:///tmp/iam-role-policy + ``` + You have now created a role named 'UdacityFlaskDeployCBKubectlRole' - You have now created a role named 'UdacityFlaskDeployCBKubectlRole' - -1. Grant the role access to the cluster. +2. Grant the role access to the cluster. The 'aws-auth ConfigMap' is used to grant role based access control to your cluster. -```bash -ROLE=" - rolearn: arn:aws:iam::$ACCOUNT_ID:role/UdacityFlaskDeployCBKubectlRole\n username: build\n groups:\n - system:masters" -kubectl get -n kube-system configmap/aws-auth -o yaml | awk "/mapRoles: \|/{print;print \"$ROLE\";next}1" > /tmp/aws-auth-patch.yml -kubectl patch configmap/aws-auth -n kube-system --patch "$(cat /tmp/aws-auth-patch.yml)" -``` + ```bash + ROLE=" - rolearn: arn:aws:iam::$ACCOUNT_ID:role/UdacityFlaskDeployCBKubectlRole\n username: build\n groups:\n - system:masters" + kubectl get -n kube-system configmap/aws-auth -o yaml | awk "/mapRoles: \|/{print;print \"$ROLE\";next}1" > /tmp/aws-auth-patch.yml + kubectl patch configmap/aws-auth -n kube-system --patch "$(cat /tmp/aws-auth-patch.yml)" + ``` -1. Generate a GitHub access token. +3. Generate a GitHub access token. A Github acces token will allow CodePipeline to monitor when a repo is changed. A token can be generated [here](https://github.com/settings/tokens/=). This token should be saved somewhere that is secure. -1. The file *buildspec.yml* instructs CodeBuild. We need a way to pass your jwt secret to the app in kubernetes securly. You will be using AWS parameter-store to do this. First add the following to your buildspec.yml file: - -```yaml -env: - parameter-store: - JWT_SECRET: JWT_SECRET -``` +4. The file *buildspec.yml* instructs CodeBuild. We need a way to pass your jwt secret to the app in kubernetes securly. You will be using AWS parameter-store to do this. First add the following to your buildspec.yml file: - This lets CodeBuild know to set an evironment variable based on a value in the parameter-store. + ```yaml + env: + parameter-store: + JWT_SECRET: JWT_SECRET + ``` + This lets CodeBuild know to set an evironment variable based on a value in the parameter-store. -1. Put secret into AWS Parameter Store +5. Put secret into AWS Parameter Store -```bash -aws ssm put-parameter --name JWT_SECRET --value "YourJWTSecret" --type SecureString -``` + ```bash + aws ssm put-parameter --name JWT_SECRET --value "YourJWTSecret" --type SecureString + ``` -1. Modify CloudFormation template. +6. Modify CloudFormation template. There is file named *ci-cd-codepipeline.cfn.yml*, this the the template file you will use to create your CodePipeline pipeline. Open this file and go to the 'Parameters' section. These are parameters that will accept values when you create a stack. Fill in the 'Default' value for the following: - **EksClusterName** : use the name of the EKS cluster you created above @@ -198,46 +190,44 @@ aws ssm put-parameter --name JWT_SECRET --value "YourJWTSecret" --type SecureStr Save this file. -1. Create a stack for CodePipeline - - Go the the [CloudFormation service](https://us-east-2.console.aws.amazon.com/cloudformation/) in the aws console. - - Press the 'Create Stack' button. - - Choose the 'Upload template to S3' option and upload the template file 'ci-cd-codepipeline.cfn.yml' - - Press 'Next'. Give the stack a name, fill in your GitHub login and the Github access token generated in step 9. - - Confirm the cluster name matches your cluster, the 'kubectl IAM role' matches the role you created above, and the repository matches the name of your forked repo. - - Create the stack. - - You can check it's status in the [CloudFormation console](https://us-east-2.console.aws.amazon.com/cloudformation/). - -1. Check the pipeline works. Once the stack is successfully created, commit a change to the master branch of your github repo. Then, in the aws console go to the [CodePipeline UI](https://us-east-2.console.aws.amazon.com/codesuite/codepipeline). You should see that the build is running. +7. Create a stack for CodePipeline + - Go the the [CloudFormation service](https://us-east-2.console.aws.amazon.com/cloudformation/) in the aws console. + - Press the 'Create Stack' button. + - Choose the 'Upload template to S3' option and upload the template file 'ci-cd-codepipeline.cfn.yml' + - Press 'Next'. Give the stack a name, fill in your GitHub login and the Github access token generated in step 9. + - Confirm the cluster name matches your cluster, the 'kubectl IAM role' matches the role you created above, and the repository matches the name of your forked repo. + - Create the stack. + + You can check it's status in the [CloudFormation console](https://us-east-2.console.aws.amazon.com/cloudformation/). -16. To test your api endpoints, get the external ip for your service: +8. Check the pipeline works. Once the stack is successfully created, commit a change to the master branch of your github repo. Then, in the aws console go to the [CodePipeline UI](https://us-east-2.console.aws.amazon.com/codesuite/codepipeline). You should see that the build is running. +9. To test your api endpoints, get the external ip for your service: -``` bash -kubectl get services simple-jwt-api -o wide -``` + ``` bash + kubectl get services simple-jwt-api -o wide + ``` - Now use the external ip url to test the app: + Now use the external ip url to test the app: -```bash -export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST :80/auth | jq -r '.token'` -curl --request GET ':80/contents' -H "Authorization: Bearer ${TOKEN}" | jq -``` + ```bash + export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST :80/auth | jq -r '.token'` + curl --request GET ':80/contents' -H "Authorization: Bearer ${TOKEN}" | jq + ``` -17. Paste the external id from above below this line for the reviewer to use: +10. Paste the external id from above below this line for the reviewer to use: **EXTERNAL IP**: -18. Add running tests as part of the build. +11. Add running tests as part of the build. - To require the unit tests to pass before our build will deploy new code to your cluster, you will add the tests to the build stage. Remember you installed the requirements and ran the unit tests locally at the beginning of this project. You will add the same commands to the *buildspec.yml*: + To require the unit tests to pass before our build will deploy new code to your cluster, you will add the tests to the build stage. Remember you installed the requirements and ran the unit tests locally at the beginning of this project. You will add the same commands to the *buildspec.yml*: - Open *buildspec.yml* - In the prebuild section, add a line to install the requirements and a line to run the tests. You may need to refer to 'pip' as 'pip3' and 'python' as 'python3' - save the file -19. You can check the tests prevent a bad deployment by breaking the tests on purpose: +12. You can check the tests prevent a bad deployment by breaking the tests on purpose: - Open the *test_main.py* file - Add `assert False` to any of the tests - Commit your code and push it to Github - Check that the build fails in [CodePipeline](https://us-east-2.console.aws.amazon.com/codesuite/codepipeline) - From 77b33254b804a2099964ebde199f99cd1e5b5b54 Mon Sep 17 00:00:00 2001 From: kbehrman Date: Mon, 29 Jul 2019 13:50:59 -0700 Subject: [PATCH 04/56] Update README.md --- README.md | 71 ++++++++++++++++++------------------------------------- 1 file changed, 23 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index b296090729..bda60ca1ea 100755 --- a/README.md +++ b/README.md @@ -97,59 +97,34 @@ GET '/contents': This requires a valid jwt token, and returns the un-encrpyted c ### Create a Kubernetes (EKS) Cluster -1. Install aws cli - - ```bash - pip install awscli --upgrade --user - ``` - - Note: If you are using a Python virtual environment, the command will be: - - ```bash - pip install awscli --upgrade - ``` - -2. [Generate a aws access key id and secret key](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) - -3. Setup your environment to use these keys: - -If you not already have a aws 'credentials' file setup, run: - - ```bash - aws configure - ``` - and use the credentials you generated in step 2. Your aws commandline tools will now use these credentials. - -4. Install the 'eksctl' tool. The 'eksctl' tool allow interaction wth a EKS cluster from the command line. To install, follow the [directions for your platform](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html). - -5. Create an EKS cluster - - ```bash - eksctl create cluster --name simple-jwt-api --version 1.12 --nodegroup-name standard-workers --nodes 3 --nodes-min 1 --nodes-max 4 --node-ami auto - ``` - This will take some time to do. Progress can be checked by visiting the aws console and selecting EKS from the services. - -6. Check the cluster is ready: - - ```bash - kubectl get nodes - ``` - - If the nodes are up and healthy, the cluster should be ready. +1. Create an EKS cluster named 'simpe-jwt-api' ### Create Pipeline You will now create a pipeline which watches your Github. When changes are checked in, it will build a new image and deploy it to your cluster. -1. Create an IAM role that CodeBuild can use to interact with EKS: - - ```bash - ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) - TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }" - echo '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:Describe*", "ssm:GetParameters" ], "Resource": "*" } ] }' > /tmp/iam-role-policy - aws iam create-role --role-name UdacityFlaskDeployCBKubectlRole --assume-role-policy-document "$TRUST" --output text --query 'Role.Arn' - aws iam put-role-policy --role-name UdacityFlaskDeployCBKubectlRole --policy-name eks-describe --policy-document file:///tmp/iam-role-policy - ``` +1. Create an IAM role that CodeBuild can use to interact with EKS. : + - Set an environment variable `ACCOUNT_ID` to the value of your AWS account id. You can do this with awscli: + ```bash + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + ``` + - Create a role policy document that allows the actions "eks:Describe*" and "ssm:GetParameters". You can do this by setting an environment variable with the role policy: + ```bash + TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }" + ``` + - Create a role named 'UdacityFlaskDeployCBKubectlRole' using the role policy document: + ```bash + aws iam create-role --role-name UdacityFlaskDeployCBKubectlRole --assume-role-policy-document "$TRUST" --output text --query 'Role.Arn' + ``` + - Create a role policy document that also allows the actions "eks:Describe*" and "ssm:GetParameters". You can create the document in your tmp directory: + ```bash + echo '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:Describe*", "ssm:GetParameters" ], "Resource": "*" } ] }' > /tmp/iam-role-policy + ``` + - Attach the policy to the 'UdacityFlaskDeployCBKubectlRole'. You can do this using awscli: + ```bash + + aws iam put-role-policy --role-name UdacityFlaskDeployCBKubectlRole --policy-name eks-describe --policy-document file:///tmp/iam-role-policy + ``` You have now created a role named 'UdacityFlaskDeployCBKubectlRole' 2. Grant the role access to the cluster. From f29194cf06292a39c1b4c2949920d8d452b6658e Mon Sep 17 00:00:00 2001 From: kbehrman Date: Mon, 29 Jul 2019 14:33:16 -0700 Subject: [PATCH 05/56] Update README.md --- README.md | 67 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index bda60ca1ea..ed48faec03 100755 --- a/README.md +++ b/README.md @@ -97,44 +97,55 @@ GET '/contents': This requires a valid jwt token, and returns the un-encrpyted c ### Create a Kubernetes (EKS) Cluster -1. Create an EKS cluster named 'simpe-jwt-api' +- Create an EKS cluster named 'simpe-jwt-api' ### Create Pipeline You will now create a pipeline which watches your Github. When changes are checked in, it will build a new image and deploy it to your cluster. 1. Create an IAM role that CodeBuild can use to interact with EKS. : - - Set an environment variable `ACCOUNT_ID` to the value of your AWS account id. You can do this with awscli: - ```bash - ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) - ``` - - Create a role policy document that allows the actions "eks:Describe*" and "ssm:GetParameters". You can do this by setting an environment variable with the role policy: - ```bash - TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }" - ``` - - Create a role named 'UdacityFlaskDeployCBKubectlRole' using the role policy document: - ```bash - aws iam create-role --role-name UdacityFlaskDeployCBKubectlRole --assume-role-policy-document "$TRUST" --output text --query 'Role.Arn' - ``` - - Create a role policy document that also allows the actions "eks:Describe*" and "ssm:GetParameters". You can create the document in your tmp directory: - ```bash - echo '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:Describe*", "ssm:GetParameters" ], "Resource": "*" } ] }' > /tmp/iam-role-policy - ``` - - Attach the policy to the 'UdacityFlaskDeployCBKubectlRole'. You can do this using awscli: - ```bash - - aws iam put-role-policy --role-name UdacityFlaskDeployCBKubectlRole --policy-name eks-describe --policy-document file:///tmp/iam-role-policy - ``` + - Set an environment variable `ACCOUNT_ID` to the value of your AWS account id. You can do this with awscli: + ```bash + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + ``` + - Create a role policy document that allows the actions "eks:Describe*" and "ssm:GetParameters". You can do this by setting an environment variable with the role policy: + ```bash + what + ``` + ```bash + TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }" + ``` + - Create a role named 'UdacityFlaskDeployCBKubectlRole' using the role policy document: + ```bash + aws iam create-role --role-name UdacityFlaskDeployCBKubectlRole --assume-role-policy-document "$TRUST" --output text --query 'Role.Arn' + ``` + - Create a role policy document that also allows the actions "eks:Describe*" and "ssm:GetParameters". You can create the document in your tmp directory: + ```bash + echo '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:Describe*", "ssm:GetParameters" ], "Resource": "*" } ] }' > /tmp/iam-role-policy + ``` + - Attach the policy to the 'UdacityFlaskDeployCBKubectlRole'. You can do this using awscli: + ```bash + aws iam put-role-policy --role-name UdacityFlaskDeployCBKubectlRole --policy-name eks-describe --policy-document file:///tmp/iam-role-policy + ``` You have now created a role named 'UdacityFlaskDeployCBKubectlRole' 2. Grant the role access to the cluster. The 'aws-auth ConfigMap' is used to grant role based access control to your cluster. - - ```bash - ROLE=" - rolearn: arn:aws:iam::$ACCOUNT_ID:role/UdacityFlaskDeployCBKubectlRole\n username: build\n groups:\n - system:masters" - kubectl get -n kube-system configmap/aws-auth -o yaml | awk "/mapRoles: \|/{print;print \"$ROLE\";next}1" > /tmp/aws-auth-patch.yml - kubectl patch configmap/aws-auth -n kube-system --patch "$(cat /tmp/aws-auth-patch.yml)" - ``` + - Get the current configmap and save it to a file: + ```bash + kubectl get -n kube-system configmap/aws-auth -o yaml > /tmp/aws-auth-patch.yml + ``` + - In the data/mapRoles section of this document add, replacing `` with your account id: + ```yml + - rolearn: arn:aws:iam:::role/UdacityFlaskDeployCBKubectlRole + username: build + groups: + - system:masters + ``` + - Now update your cluster's configmap: + ```bash + kubectl patch configmap/aws-auth -n kube-system --patch "$(cat /tmp/aws-auth-patch.yml)" + ``` 3. Generate a GitHub access token. A Github acces token will allow CodePipeline to monitor when a repo is changed. A token can be generated [here](https://github.com/settings/tokens/=). From 7c49dd18c642b7c0c2fe17e9ff371c258722eb0c Mon Sep 17 00:00:00 2001 From: kbehrman Date: Mon, 29 Jul 2019 14:35:09 -0700 Subject: [PATCH 06/56] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index ed48faec03..2f1f5adcfd 100755 --- a/README.md +++ b/README.md @@ -109,9 +109,6 @@ You will now create a pipeline which watches your Github. When changes are check ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) ``` - Create a role policy document that allows the actions "eks:Describe*" and "ssm:GetParameters". You can do this by setting an environment variable with the role policy: - ```bash - what - ``` ```bash TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }" ``` From da52c1f4c7dec08fadaacc3e63049fee514fe33d Mon Sep 17 00:00:00 2001 From: Stephen Welch Date: Thu, 1 Aug 2019 12:03:41 -0700 Subject: [PATCH 07/56] Updated README to move detailed instruction into the classroom. --- README.md | 232 +++++++----------------------------------------------- 1 file changed, 27 insertions(+), 205 deletions(-) diff --git a/README.md b/README.md index 2f1f5adcfd..ebfe63c3da 100755 --- a/README.md +++ b/README.md @@ -1,216 +1,38 @@ -# Deploying Flask API +# Deploying a Flask API -## Initial setup -1. Fork this project by pressing the fork buton -2. Locally clone your Forked version. You can now begin modifying it. - -## Containerizing and Running Locally -The supplied flask app is a very simple api with three endpoints. -GET '/': This is a simple health check, which returns the response 'Healthy'. -POST '/auth': This takes a email and password as json arguments and returns a jwt token base on a custom secret. -GET '/contents': This requires a valid jwt token, and returns the un-encrpyted contents of that token. - -### Run the Api using Flask Server -1. Install python dependencies. These dependencies are kept in a requirements.txt file. To install them, use pip: - ```bash - pip install -r requirements.txt - ``` -2. Set up the environment. The following environment variable is required: - - **JWT_SECRET** - The secret used to make the JWT token, for the purpose of this course it can be any string. - - The following environment variable is optional: - - **LOG_LEVEL** - The level of logging. Will default to 'INFO', but when debugging an app locally, you may want to set it to 'DEBUG' - - ```bash - export JWT_SECRET=myjwtsecret - export LOG_LEVEL=DEBUG - ``` - -3. Run the app using the Flask server, from the flask-app directory, run: - ```bash - python app/main.py - ``` - - To try the api endpoints, open a new shell and run, replacing '\' and '\' with and any values: - - ```bash - export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST localhost:80/auth | jq -r '.token'` - ``` - - This calls the endpoint 'localhost:80/auth' with the '{"email":"","password":""}' as the message body. The return value is a jwt token based on the secret you supplied. We are assigning that secret to the environment variable 'TOKEN'. To see the jwt token, run: - - ```bash - echo $TOKEN - ``` - To call the 'contents' endpoint, which decrpyts the token and returns it content, run: - - ```bash - curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TOKEN}" | jq . - ``` - You should see the email that you passed in as one of the values. - -### Dockerize and Run Locally - -1. Install Docker: [installation instructions](https://docs.docker.com/install/) - -2. Create a Docker file. A Docker file decribes how to build a Docker image. Create a file named 'Dockerfile' in the app repo. The contents of the file describe the steps in creating a Docker image. Your Dockerfile should: - - use the 'python:strech' image as a source image - - Setup an app directory for your code - - Install needed python requirements - - Define an entrypoint which will run the main app using the gunicorn WSGI server - - gunicorn should be run with the arguments: - - ```bash - gunicorn -b :8080 main:APP - ``` - - -3. Create a file named 'env_file' and use it to set the environment variables which will be run locally in your container. Here we do not need the export command, just an equals sign: - - ``` - \=\ - ``` +This is the project starter repo for the fourth course in the [Udacity Full Stack Nanodegree](https://www.udacity.com/course/full-stack-web-developer-nanodegree--nd004): Server Deployment, Containerization, and Testing. -4. Build a Local Docker Image. To build a Docker image run: - ```bash - docker build -t jwt-api-test . - ``` +In this project you will containerize and deploy a Flask API to a Kubernetes cluster using Docker, AWS EKS, CodePipeline, and CodeBuild. -5. Run the image locally, using the 'gunicorn' server: - ```bash - docker run --env-file=env_file -p 80:8080 jwt-api-test - ``` +The Flask app that will be used for this project consists of a simple API with three endpoints: - To use the endpoints use the same curl commands as before: +- `GET '/'`: This is a simple health check, which returns the response 'Healthy'. +- `POST '/auth'`: This takes a email and password as json arguments and returns a JWT based on a custom secret. +- `GET '/contents'`: This requires a valid JWT, and returns the un-encrpyted contents of that token. - ```bash - export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST localhost:80/auth | jq -r '.token'` - ``` - ```bash - curl --request GET 'http://127.0.0.1:80/contents' -H "Authorization: Bearer ${TOKEN}" | jq . - ``` +The app relies on a secret set as the environment variable `JWT_SECRET` to produce a JWT. The built-in Flask server is adequate for local development, but not production, so you will be using the production-ready [Gunicorn](https://gunicorn.org/) server when deploying the app. -## Deployment to Kubernetes using CodePipeline and CodeBuild - -### Create a Kubernetes (EKS) Cluster - -- Create an EKS cluster named 'simpe-jwt-api' - -### Create Pipeline -You will now create a pipeline which watches your Github. When changes are checked in, it will build a new image and deploy it to your cluster. - - -1. Create an IAM role that CodeBuild can use to interact with EKS. : - - Set an environment variable `ACCOUNT_ID` to the value of your AWS account id. You can do this with awscli: - ```bash - ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) - ``` - - Create a role policy document that allows the actions "eks:Describe*" and "ssm:GetParameters". You can do this by setting an environment variable with the role policy: - ```bash - TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::${ACCOUNT_ID}:root\" }, \"Action\": \"sts:AssumeRole\" } ] }" - ``` - - Create a role named 'UdacityFlaskDeployCBKubectlRole' using the role policy document: - ```bash - aws iam create-role --role-name UdacityFlaskDeployCBKubectlRole --assume-role-policy-document "$TRUST" --output text --query 'Role.Arn' - ``` - - Create a role policy document that also allows the actions "eks:Describe*" and "ssm:GetParameters". You can create the document in your tmp directory: - ```bash - echo '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:Describe*", "ssm:GetParameters" ], "Resource": "*" } ] }' > /tmp/iam-role-policy - ``` - - Attach the policy to the 'UdacityFlaskDeployCBKubectlRole'. You can do this using awscli: - ```bash - aws iam put-role-policy --role-name UdacityFlaskDeployCBKubectlRole --policy-name eks-describe --policy-document file:///tmp/iam-role-policy - ``` - You have now created a role named 'UdacityFlaskDeployCBKubectlRole' - -2. Grant the role access to the cluster. -The 'aws-auth ConfigMap' is used to grant role based access control to your cluster. - - Get the current configmap and save it to a file: - ```bash - kubectl get -n kube-system configmap/aws-auth -o yaml > /tmp/aws-auth-patch.yml - ``` - - In the data/mapRoles section of this document add, replacing `` with your account id: - ```yml - - rolearn: arn:aws:iam:::role/UdacityFlaskDeployCBKubectlRole - username: build - groups: - - system:masters - ``` - - Now update your cluster's configmap: - ```bash - kubectl patch configmap/aws-auth -n kube-system --patch "$(cat /tmp/aws-auth-patch.yml)" - ``` - -3. Generate a GitHub access token. - A Github acces token will allow CodePipeline to monitor when a repo is changed. A token can be generated [here](https://github.com/settings/tokens/=). -This token should be saved somewhere that is secure. - -4. The file *buildspec.yml* instructs CodeBuild. We need a way to pass your jwt secret to the app in kubernetes securly. You will be using AWS parameter-store to do this. First add the following to your buildspec.yml file: - - ```yaml - env: - parameter-store: - JWT_SECRET: JWT_SECRET - ``` - This lets CodeBuild know to set an evironment variable based on a value in the parameter-store. - -5. Put secret into AWS Parameter Store - - ```bash - aws ssm put-parameter --name JWT_SECRET --value "YourJWTSecret" --type SecureString - ``` - -6. Modify CloudFormation template. - - There is file named *ci-cd-codepipeline.cfn.yml*, this the the template file you will use to create your CodePipeline pipeline. Open this file and go to the 'Parameters' section. These are parameters that will accept values when you create a stack. Fill in the 'Default' value for the following: - - **EksClusterName** : use the name of the EKS cluster you created above - - **GitSourceRepo** : use the name of your project's github repo. - - **GitHubUser** : use your github user name - - **KubectlRoleName** : use the name of the role you created for kubectl above - - Save this file. - -7. Create a stack for CodePipeline - - Go the the [CloudFormation service](https://us-east-2.console.aws.amazon.com/cloudformation/) in the aws console. - - Press the 'Create Stack' button. - - Choose the 'Upload template to S3' option and upload the template file 'ci-cd-codepipeline.cfn.yml' - - Press 'Next'. Give the stack a name, fill in your GitHub login and the Github access token generated in step 9. - - Confirm the cluster name matches your cluster, the 'kubectl IAM role' matches the role you created above, and the repository matches the name of your forked repo. - - Create the stack. - - You can check it's status in the [CloudFormation console](https://us-east-2.console.aws.amazon.com/cloudformation/). - -8. Check the pipeline works. Once the stack is successfully created, commit a change to the master branch of your github repo. Then, in the aws console go to the [CodePipeline UI](https://us-east-2.console.aws.amazon.com/codesuite/codepipeline). You should see that the build is running. - -9. To test your api endpoints, get the external ip for your service: - - ``` bash - kubectl get services simple-jwt-api -o wide - ``` - - Now use the external ip url to test the app: - - ```bash - export TOKEN=`curl -d '{"email":"","password":""}' -H "Content-Type: application/json" -X POST :80/auth | jq -r '.token'` - curl --request GET ':80/contents' -H "Authorization: Bearer ${TOKEN}" | jq - ``` +## Initial setup +1. Fork this project to your Github account. +2. Locally clone your forked version to begin working on the project. -10. Paste the external id from above below this line for the reviewer to use: +## Dependencies - **EXTERNAL IP**: +- Docker Engine + - Installation instructions for all OSes can be found [here](https://docs.docker.com/install/). + - For Mac users, if you have no previous Docker Toolbox installation, you can install Docker Desktop for Mac. If you already have a Docker Toolbox installation, please read [this](https://docs.docker.com/docker-for-mac/docker-toolbox/) before installing. + - AWS Account + - You can create an AWS account by signing up [here](https://aws.amazon.com/#). + +## Project Steps -11. Add running tests as part of the build. +Completing the project involves several steps: - To require the unit tests to pass before our build will deploy new code to your cluster, you will add the tests to the build stage. Remember you installed the requirements and ran the unit tests locally at the beginning of this project. You will add the same commands to the *buildspec.yml*: - - Open *buildspec.yml* - - In the prebuild section, add a line to install the requirements and a line to run the tests. You may need to refer to 'pip' as 'pip3' and 'python' as 'python3' - - save the file +1. Write a Dockerfile for a simple Flask API +2. Build and test the container locally +3. Create an EKS cluster +4. Store a secret using AWS Parameter Store +5. Create a CodePipeline pipeline triggered by GitHub checkins +6. Create a CodeBuild stage which will build, test, and deploy your code -12. You can check the tests prevent a bad deployment by breaking the tests on purpose: - - Open the *test_main.py* file - - Add `assert False` to any of the tests - - Commit your code and push it to Github - - Check that the build fails in [CodePipeline](https://us-east-2.console.aws.amazon.com/codesuite/codepipeline) +For more detail about each of these steps, see the project lesson [here](https://classroom.udacity.com/nanodegrees/nd004/parts/1d842ebf-5b10-4749-9e5e-ef28fe98f173/modules/ac13842f-c841-4c1a-b284-b47899f4613d/lessons/becb2dac-c108-4143-8f6c-11b30413e28d/concepts/092cdb35-28f7-4145-b6e6-6278b8dd7527). \ No newline at end of file From 63433f4c306b8b4edbecf66cf512ed6370edb757 Mon Sep 17 00:00:00 2001 From: Stephen Welch Date: Fri, 22 Nov 2019 11:15:40 -0800 Subject: [PATCH 08/56] Update buildspec.yml Update versions of kubectl and aws-iam-authenticator --- buildspec.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 7f8a116e27..0cc705ccc9 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -5,8 +5,8 @@ version: 0.2 phases: install: commands: - - curl -sS -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/bin/linux/amd64/aws-iam-authenticator - - curl -sS -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/bin/linux/amd64/kubectl + - curl -sS -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.14.6/2019-08-22/bin/linux/amd64/aws-iam-authenticator + - curl -sS -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.14.6/2019-08-22/bin/linux/amd64/kubectl - chmod +x ./kubectl ./aws-iam-authenticator - export PATH=$PWD/:$PATH - apt-get update && apt-get -y install jq python3-pip python3-dev && pip3 install --upgrade awscli From e5e40936499bfa1c041a017ee5dc6660cac76f81 Mon Sep 17 00:00:00 2001 From: "kr.behrman@gmail.com" Date: Sun, 28 Jun 2020 09:15:10 -0700 Subject: [PATCH 09/56] Updates to work with current systems --- buildspec.yml | 27 +++++++++++++++------------ ci-cd-codepipeline.cfn.yml | 5 +++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 0cc705ccc9..fd54b14792 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -4,12 +4,22 @@ version: 0.2 phases: install: + runtime-versions: + python: 3.7 commands: - - curl -sS -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.14.6/2019-08-22/bin/linux/amd64/aws-iam-authenticator - - curl -sS -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.14.6/2019-08-22/bin/linux/amd64/kubectl + - echo 'about to call dockerd' + - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2& + - timeout 15 sh -c "until docker info; do echo .; sleep 1; done" + - curl -sS -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/bin/linux/amd64/aws-iam-authenticator + # Get latest stable release kubectl + - curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl + # Command for specific kubectl version: + #- curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl - chmod +x ./kubectl ./aws-iam-authenticator + - echo `kubectl version` - export PATH=$PWD/:$PATH - - apt-get update && apt-get -y install jq python3-pip python3-dev && pip3 install --upgrade awscli + - python -m pip install --upgrade --force pip + - apt-get update && apt-get -y install jq && pip install --upgrade awscli pre_build: commands: - TAG="$REPOSITORY_NAME.$REPOSITORY_BRANCH.$ENVIRONMENT_NAME.$(date +%Y-%m-%d.%H.%M.%S).$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)" @@ -23,15 +33,8 @@ phases: post_build: commands: - docker push $REPOSITORY_URI:$TAG - - CREDENTIALS=$(aws sts assume-role --role-arn $EKS_KUBECTL_ROLE_ARN --role-session-name codebuild-kubectl --duration-seconds 900) - - export AWS_ACCESS_KEY_ID="$(echo ${CREDENTIALS} | jq -r '.Credentials.AccessKeyId')" - - export AWS_SECRET_ACCESS_KEY="$(echo ${CREDENTIALS} | jq -r '.Credentials.SecretAccessKey')" - - export AWS_SESSION_TOKEN="$(echo ${CREDENTIALS} | jq -r '.Credentials.SessionToken')" - - export AWS_EXPIRATION=$(echo ${CREDENTIALS} | jq -r '.Credentials.Expiration') - - aws eks update-kubeconfig --name $EKS_CLUSTER_NAME - - kubectl apply -f simple_jwt_api.yml + - aws eks update-kubeconfig --name $EKS_CLUSTER_NAME --role-arn $EKS_KUBECTL_ROLE_ARN + - kubectl apply -f simple_jwt_api.yml - printf '[{"name":"simple_jwt_api","imageUri":"%s"}]' $REPOSITORY_URI:$TAG > build.json - - pwd - - ls artifacts: files: build.json diff --git a/ci-cd-codepipeline.cfn.yml b/ci-cd-codepipeline.cfn.yml index 4787331893..92f661ab5c 100755 --- a/ci-cd-codepipeline.cfn.yml +++ b/ci-cd-codepipeline.cfn.yml @@ -48,8 +48,8 @@ Parameters: CodeBuildDockerImage: Type: String - Default: aws/codebuild/docker:17.09.0 - Description: Default AWS CodeBuild Docker optimized image + Default: aws/codebuild/standard:4.0 + Description: AWS CodeBuild Docker optimized image MinLength: 3 MaxLength: 100 ConstraintDescription: You must enter a CodeBuild Docker image @@ -324,6 +324,7 @@ Resources: Value: !Ref EksClusterName - Name: EKS_KUBECTL_ROLE_ARN Value: !Sub arn:aws:iam::${AWS::AccountId}:role/${KubectlRoleName} + PrivilegedMode: true Name: !Ref AWS::StackName ServiceRole: !GetAtt CodeBuildServiceRole.Arn DependsOn: KubectlAssumeRoleCustomResource From d97e681a8e10f77cd870e2ee17320d950b3c986a Mon Sep 17 00:00:00 2001 From: kbehrman Date: Tue, 7 Jul 2020 18:12:10 -0700 Subject: [PATCH 10/56] Update .gitignore ignore .env_file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 811d05a927..91cbe2303b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ _mailinglist .idea/ docs/_build/ __pycache__ +.env_file # Coverage reports htmlcov/ From 6f81589ccb49b8acbfd93782aa38ccf858dbe11b Mon Sep 17 00:00:00 2001 From: SudKul Date: Thu, 25 Feb 2021 17:45:31 +0530 Subject: [PATCH 11/56] Add SheBangLine to main.py --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 7663afa7b1..f6c8219f37 100755 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python """ A simple app to create a JWT token. """ From be4cce8d4f939bf0a0944563e143b30f37d76f6e Mon Sep 17 00:00:00 2001 From: SudKul Date: Fri, 26 Feb 2021 15:22:56 +0530 Subject: [PATCH 12/56] Create role and add role to configmap --- Dockerfile | 16 ++++++++++++++++ iam-role-policy.json | 8 ++++++++ trust.json | 12 ++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 Dockerfile create mode 100644 iam-role-policy.json create mode 100644 trust.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..4ab4c6559b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM python:stretch + +COPY . /app +WORKDIR /app + +RUN pip install --upgrade pip +RUN pip install -r requirements.txt + +RUN apt-get update && apt-get install -y locales && locale-gen en_US.UTF-8 +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 +ENV PYTHONIOENCODING=utf-8 + +ENTRYPOINT ["gunicorn" , "-b", ":8080", "main:APP"] diff --git a/iam-role-policy.json b/iam-role-policy.json new file mode 100644 index 0000000000..b18b228d7d --- /dev/null +++ b/iam-role-policy.json @@ -0,0 +1,8 @@ +{ + "Version": "2012-10-17", + "Statement":[{ + "Effect": "Allow", + "Action": ["eks:Describe*", "ssm:GetParameters"], + "Resource":"*" + }] +} \ No newline at end of file diff --git a/trust.json b/trust.json new file mode 100644 index 0000000000..a85a90b045 --- /dev/null +++ b/trust.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::644752792305:root" + }, + "Action": "sts:AssumeRole" + } + ] +} \ No newline at end of file From b717b73740937e6d5c09790c740b4582df335937 Mon Sep 17 00:00:00 2001 From: SudKul Date: Fri, 26 Feb 2021 15:23:44 +0530 Subject: [PATCH 13/56] Create role and add role to configmap --- aws-auth-patch.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 aws-auth-patch.yml diff --git a/aws-auth-patch.yml b/aws-auth-patch.yml new file mode 100644 index 0000000000..ea47acd381 --- /dev/null +++ b/aws-auth-patch.yml @@ -0,0 +1,22 @@ +apiVersion: v1 +data: + mapRoles: | + - groups: + - system:masters + rolearn: arn:aws:iam::644752792305:role/UdacityFlaskDeployCBKubectlRole + username: build + - groups: + - system:bootstrappers + - system:nodes + rolearn: arn:aws:iam::644752792305:role/eksctl-simple-jwt-api-nodegroup-n-NodeInstanceRole-17C402QC9VF6L + username: system:node:{{EC2PrivateDNSName}} + mapUsers: | + [] +kind: ConfigMap +metadata: + creationTimestamp: "2021-02-26T07:40:38Z" + name: aws-auth + namespace: kube-system + resourceVersion: "5992" + selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth + uid: 5bf363cb-504c-4289-93ce-74257aff0de4 From fb856ffd4d06f8ace333ca91ac82c3d5318e1708 Mon Sep 17 00:00:00 2001 From: SudKul Date: Fri, 26 Feb 2021 19:20:59 +0530 Subject: [PATCH 14/56] Fix the template to allow creating the KubectlAssumeRoleCustomResource --- ci-cd-codepipeline.cfn.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ci-cd-codepipeline.cfn.yml b/ci-cd-codepipeline.cfn.yml index 92f661ab5c..12f5319cba 100755 --- a/ci-cd-codepipeline.cfn.yml +++ b/ci-cd-codepipeline.cfn.yml @@ -9,7 +9,7 @@ Parameters: EksClusterName: Type: String Description: The name of the EKS cluster created - Default: + Default: simple-jwt-api MinLength: 1 MaxLength: 100 ConstraintDescription: You must enter the EKS cluster name @@ -17,7 +17,7 @@ Parameters: GitSourceRepo: Type: String Description: GitHub source repository - must contain a Dockerfile and buildspec.yml in the base - Default: + Default: FSND-Deploy-Flask-App-to-Kubernetes-Using-EKS MinLength: 1 MaxLength: 100 ConstraintDescription: You must enter a GitHub repository name @@ -32,6 +32,7 @@ Parameters: GitHubToken: Type: String + Default: d5b62e18a198d58891fc3899aa3e4570c4bf4713 NoEcho: true Description: GitHub API token - see https://github.com/blog/1509-personal-api-tokens MinLength: 3 @@ -40,7 +41,7 @@ Parameters: GitHubUser: Type: String - Default: + Default: SudKul Description: GitHub username or organization MinLength: 3 MaxLength: 100 @@ -56,7 +57,7 @@ Parameters: KubectlRoleName: Type: String - Default: + Default: UdacityFlaskDeployCBKubectlRole Description: IAM role used by kubectl to interact with EKS cluster MinLength: 3 MaxLength: 100 @@ -155,7 +156,7 @@ Resources: response['Data'] = {"Message": "Resource creation failed"} response_body = json.dumps(response) - headers = {'content-type': '', "content-length": len(response_body) } + headers = {'content-type': '', "content-length": str(len(response_body)) } put_response = requests.put(event['ResponseURL'], headers=headers, data=response_body) return response From 37f943acffed78458e364cbc0460360083334f9a Mon Sep 17 00:00:00 2001 From: SudKul Date: Sat, 27 Feb 2021 00:35:02 +0530 Subject: [PATCH 15/56] Do not push your Github token --- .gitignore | 2 +- ci-cd-codepipeline.cfn.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 91cbe2303b..d8258413a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .DS_Store -.env +.env* .flaskenv *.pyc *.pyo diff --git a/ci-cd-codepipeline.cfn.yml b/ci-cd-codepipeline.cfn.yml index 12f5319cba..a391876ab0 100755 --- a/ci-cd-codepipeline.cfn.yml +++ b/ci-cd-codepipeline.cfn.yml @@ -32,7 +32,6 @@ Parameters: GitHubToken: Type: String - Default: d5b62e18a198d58891fc3899aa3e4570c4bf4713 NoEcho: true Description: GitHub API token - see https://github.com/blog/1509-personal-api-tokens MinLength: 3 From fa3f3e6c523661ed5c4b17e31d5edd63758f78aa Mon Sep 17 00:00:00 2001 From: SudKul Date: Sun, 7 Mar 2021 21:33:26 +0530 Subject: [PATCH 16/56] Add trust.json --- trust.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trust.json b/trust.json index a85a90b045..7d03cc3a8a 100644 --- a/trust.json +++ b/trust.json @@ -4,7 +4,7 @@ { "Effect": "Allow", "Principal": { - "AWS": "arn:aws:iam::644752792305:root" + "AWS": "arn:aws:iam::480722495888:root" }, "Action": "sts:AssumeRole" } From 185056ad53e39802dad33072416b797540c66c78 Mon Sep 17 00:00:00 2001 From: SudKul Date: Sun, 7 Mar 2021 21:36:21 +0530 Subject: [PATCH 17/56] Delete Dockerfile --- Dockerfile | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 4ab4c6559b..0000000000 --- a/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM python:stretch - -COPY . /app -WORKDIR /app - -RUN pip install --upgrade pip -RUN pip install -r requirements.txt - -RUN apt-get update && apt-get install -y locales && locale-gen en_US.UTF-8 -RUN locale-gen en_US.UTF-8 -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en -ENV LC_ALL en_US.UTF-8 -ENV PYTHONIOENCODING=utf-8 - -ENTRYPOINT ["gunicorn" , "-b", ":8080", "main:APP"] From 835f6e59c2ecdc88c94fd0af1e217290e85067a1 Mon Sep 17 00:00:00 2001 From: SudKul Date: Sun, 7 Mar 2021 21:41:31 +0530 Subject: [PATCH 18/56] Remove the iam-role-policy.json and trust.json files --- iam-role-policy.json | 8 -------- trust.json | 12 ------------ 2 files changed, 20 deletions(-) delete mode 100644 iam-role-policy.json delete mode 100644 trust.json diff --git a/iam-role-policy.json b/iam-role-policy.json deleted file mode 100644 index b18b228d7d..0000000000 --- a/iam-role-policy.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement":[{ - "Effect": "Allow", - "Action": ["eks:Describe*", "ssm:GetParameters"], - "Resource":"*" - }] -} \ No newline at end of file diff --git a/trust.json b/trust.json deleted file mode 100644 index 7d03cc3a8a..0000000000 --- a/trust.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "AWS": "arn:aws:iam::480722495888:root" - }, - "Action": "sts:AssumeRole" - } - ] -} \ No newline at end of file From 5a0a9d8887d74adb57fbe2e111bc4fcb7ee9a47e Mon Sep 17 00:00:00 2001 From: SudKul Date: Sun, 7 Mar 2021 21:49:50 +0530 Subject: [PATCH 19/56] Add a sample aws-auth-patch.yml file --- aws-auth-patch.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aws-auth-patch.yml b/aws-auth-patch.yml index ea47acd381..b6d9b9c26c 100644 --- a/aws-auth-patch.yml +++ b/aws-auth-patch.yml @@ -1,3 +1,6 @@ +# This is a sample aws-auth-patch.yml file. +# Actual aws-auth-patch.yml will be created at /System/Volumes/Data/private/tmp/aws-auth-patch.yml path. + apiVersion: v1 data: mapRoles: | From 67925eb527d4289834578c2804608af736e95d05 Mon Sep 17 00:00:00 2001 From: SudKul <48475411+SudKul@users.noreply.github.com> Date: Mon, 15 Mar 2021 18:10:36 +0530 Subject: [PATCH 20/56] Update requirements.txt Specify package version --- requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 504cee7240..30f3e22ddf 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pyjwt -flask -gunicorn -pytest +pyjwt=1.7.1 +flask=1.1.2 +gunicorn=20.0.4 +pytest=6.2.2 From 2cc57ca9bfd861b8fc237cf63bbd3980dc814270 Mon Sep 17 00:00:00 2001 From: SudKul <48475411+SudKul@users.noreply.github.com> Date: Mon, 15 Mar 2021 18:38:20 +0530 Subject: [PATCH 21/56] Update requirements.txt --- requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 30f3e22ddf..33052c2577 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pyjwt=1.7.1 -flask=1.1.2 -gunicorn=20.0.4 -pytest=6.2.2 +pyjwt==1.7.1 +flask==1.1.2 +gunicorn==20.0.4 +pytest==6.2.2 From 81abf16f875effc3376884935a2ed30a4c6565f5 Mon Sep 17 00:00:00 2001 From: SudKul <48475411+SudKul@users.noreply.github.com> Date: Mon, 3 May 2021 15:27:27 +0530 Subject: [PATCH 22/56] Create manual.yml --- .github/workflows/manual.yml | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/manual.yml diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml new file mode 100644 index 0000000000..d06bfa4ce5 --- /dev/null +++ b/.github/workflows/manual.yml @@ -0,0 +1,47 @@ +# Workflow to ensure whenever a Github PR is submitted, +# a JIRA ticket gets created automatically. +name: Manual Workflow + +# Controls when the action will run. +on: + # Triggers the workflow on pull request events but only for the master branch + pull_request: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + test-transition-issue: + name: Convert Github Issue to Jira Issue + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@master + + - name: Login + uses: atlassian/gajira-login@master + env: + JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} + JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} + JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + + - name: Create NEW JIRA ticket + id: create + uses: atlassian/gajira-create@master + with: + project: CONUPDATE + issuetype: Task + summary: | + Github PR - nd0044 v2 Full Stack Web Developer (refresh) | Repo: FSND-Deploy-Flask-App-to-Kubernetes-Using-EKS | PR# ${{github.event.number}} + description: | + Repo link: https://github.com/${{ github.repository }} + Course name: 5. Server Deployment, Containerization and Testing + PR no. ${{ github.event.pull_request.number }} + PR title: ${{ github.event.pull_request.title }} + PR description: ${{ github.event.pull_request.description }} + In addition, please resolve other issues, if any. + fields: '{"components": [{"name":"Github PR"}], "customfield_16449":"https://classroom.udacity.com/nanodegrees/nd0044/dashboard/overview", "customfield_16450":"Resolve the PR", "labels": ["github"]}' + + - name: Log created issue + run: echo "Issue ${{ steps.create.outputs.issue }} was created" From eebc1e7f9e709722c3df5839ec5dc0d5773fd3b1 Mon Sep 17 00:00:00 2001 From: SudKul <48475411+SudKul@users.noreply.github.com> Date: Mon, 3 May 2021 15:27:47 +0530 Subject: [PATCH 23/56] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d8258413a7..9500e81546 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ htmlcov/ # Direnv .envrc .direnv + +.github/** From 4874da4d4f75154273ddc27e5fe45b6e2caefd64 Mon Sep 17 00:00:00 2001 From: SudKul <48475411+SudKul@users.noreply.github.com> Date: Wed, 5 May 2021 12:06:55 +0530 Subject: [PATCH 24/56] Update manual.yml --- .github/workflows/manual.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index d06bfa4ce5..e01aedfd43 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -5,8 +5,8 @@ name: Manual Workflow # Controls when the action will run. on: # Triggers the workflow on pull request events but only for the master branch - pull_request: - branches: [ master ] + pull_request_target: + types: [assigned, opened, reopened] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: From f7c665e55da6c1e2b8574b5c4e06b8251bb8c390 Mon Sep 17 00:00:00 2001 From: SudKul Date: Mon, 10 May 2021 15:22:34 +0530 Subject: [PATCH 25/56] Add exercise resource --- examples/buildspec.yml | 9 ++ examples/buildspec.yml.zip | Bin 0 -> 283 bytes examples/simple-pipeline-build.yml | 228 +++++++++++++++++++++++++++++ 3 files changed, 237 insertions(+) create mode 100644 examples/buildspec.yml create mode 100644 examples/buildspec.yml.zip create mode 100644 examples/simple-pipeline-build.yml diff --git a/examples/buildspec.yml b/examples/buildspec.yml new file mode 100644 index 0000000000..66a2c7a365 --- /dev/null +++ b/examples/buildspec.yml @@ -0,0 +1,9 @@ +--- +version: 0.2 + + +phases: + build: + commands: + - echo Hello from Code Build! + diff --git a/examples/buildspec.yml.zip b/examples/buildspec.yml.zip new file mode 100644 index 0000000000000000000000000000000000000000..7be46347d7fea5aee6feaaac5a22397a6294ac8b GIT binary patch literal 283 zcmWIWW@Zs#-~htc6PE-rKtVW==4DV|NGi?DNhvN!P1dW-%?St{lx)xZ=Qc<-&`fyoJ^GKg^gJ_j1}+ zOP$YNF6E!po^e>rk9owQkg;~3>u**A6_ulkOEuQ56W#50(5$cX1#^HmJIAfFx)1$< rMuXfF;LXS+!i;b$vK+{*FtDT%#3IS%0p6@^AWe)w7!9OXfjA5RT5?v9 literal 0 HcmV?d00001 diff --git a/examples/simple-pipeline-build.yml b/examples/simple-pipeline-build.yml new file mode 100644 index 0000000000..fd44f15bc6 --- /dev/null +++ b/examples/simple-pipeline-build.yml @@ -0,0 +1,228 @@ +Parameters: + SourceObjectKey: + Description: 'S3 source artifact' + Type: String + Default: buildspec.yml.zip + CodeBuildDockerImage: + Type: String + Default: aws/codebuild/standard:4.0 + Description: AWS CodeBuild Docker optimized image + MinLength: 3 + MaxLength: 100 + ConstraintDescription: You must enter a CodeBuild Docker image + +Resources: + SourceBucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: Enabled + CodePipelineArtifactStoreBucket: + Type: AWS::S3::Bucket + CodePipelineArtifactStoreBucketPolicy: + Type: AWS::S3::BucketPolicy + Properties: + Bucket: !Ref CodePipelineArtifactStoreBucket + PolicyDocument: + Version: 2012-10-17 + Statement: + - + Sid: DenyUnEncryptedObjectUploads + Effect: Deny + Principal: '*' + Action: s3:PutObject + Resource: !Join [ '', [ !GetAtt CodePipelineArtifactStoreBucket.Arn, '/*' ] ] + Condition: + StringNotEquals: + s3:x-amz-server-side-encryption: aws:kms + - + Sid: DenyInsecureConnections + Effect: Deny + Principal: '*' + Action: s3:* + Resource: !Join [ '', [ !GetAtt CodePipelineArtifactStoreBucket.Arn, '/*' ] ] + Condition: + Bool: + aws:SecureTransport: false + CodePipelineServiceRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - + Effect: Allow + Principal: + Service: + - codepipeline.amazonaws.com + Action: sts:AssumeRole + Path: / + Policies: + - + PolicyName: AWS-CodePipeline-Service-3 + PolicyDocument: + Version: 2012-10-17 + Statement: + - + Effect: Allow + Action: + - codecommit:CancelUploadArchive + - codecommit:GetBranch + - codecommit:GetCommit + - codecommit:GetUploadArchiveStatus + - codecommit:UploadArchive + Resource: '*' + - + Effect: Allow + Action: + - codedeploy:CreateDeployment + - codedeploy:GetApplicationRevision + - codedeploy:GetDeployment + - codedeploy:GetDeploymentConfig + - codedeploy:RegisterApplicationRevision + Resource: '*' + - + Effect: Allow + Action: + - codebuild:BatchGetBuilds + - codebuild:StartBuild + Resource: '*' + - + Effect: Allow + Action: + - devicefarm:ListProjects + - devicefarm:ListDevicePools + - devicefarm:GetRun + - devicefarm:GetUpload + - devicefarm:CreateUpload + - devicefarm:ScheduleRun + Resource: '*' + - + Effect: Allow + Action: + - lambda:InvokeFunction + - lambda:ListFunctions + Resource: '*' + - + Effect: Allow + Action: + - iam:PassRole + Resource: '*' + - + Effect: Allow + Action: + - elasticbeanstalk:* + - ec2:* + - elasticloadbalancing:* + - autoscaling:* + - cloudwatch:* + - s3:* + - sns:* + - cloudformation:* + - rds:* + - sqs:* + - ecs:* + Resource: '*' + AppPipeline: + Type: AWS::CodePipeline::Pipeline + Properties: + Name: s3-events-pipeline + RoleArn: + !GetAtt CodePipelineServiceRole.Arn + Stages: + - + Name: Source + Actions: + - + Name: SourceAction + ActionTypeId: + Category: Source + Owner: AWS + Version: 1 + Provider: S3 + OutputArtifacts: + - Name: SourceOutput + Configuration: + S3Bucket: !Ref SourceBucket + S3ObjectKey: !Ref SourceObjectKey + PollForSourceChanges: false + RunOrder: 1 + - Name: Build + Actions: + - Name: Build + ActionTypeId: + Category: Build + Owner: AWS + Version: 1 + Provider: CodeBuild + Configuration: + ProjectName: !Ref CodeBuildProject + InputArtifacts: + - Name: SourceOutput + OutputArtifacts: + - Name: BuildOutput + RunOrder: 1 + ArtifactStore: + Type: S3 + Location: !Ref CodePipelineArtifactStoreBucket + CodeBuildProject: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: CODEPIPELINE + Source: + Type: CODEPIPELINE + Environment: + ComputeType: BUILD_GENERAL1_SMALL + Type: LINUX_CONTAINER + Image: !Ref CodeBuildDockerImage + PrivilegedMode: true + Name: !Ref AWS::StackName + ServiceRole: !GetAtt CodeBuildServiceRole.Arn + CodeBuildServiceRole: + Type: AWS::IAM::Role + Properties: + Path: / + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: codebuild.amazonaws.com + Action: sts:AssumeRole + Policies: + - PolicyName: root + PolicyDocument: + Version: 2012-10-17 + Statement: + - Resource: '*' + Effect: Allow + Action: + - ssm:GetParameters + - Resource: '*' + Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + - Resource: '*' + Effect: Allow + Action: + - ecr:GetAuthorizationToken + - Resource: '*' + Effect: Allow + Action: + - ec2:CreateNetworkInterface + - ec2:DescribeDhcpOptions + - ec2:DescribeNetworkInterfaces + - ec2:DeleteNetworkInterface + - ec2:DescribeSubnets + - ec2:DescribeSecurityGroups + - ec2:DescribeVpcs + - ec2:CreateNetworkInterfacePermission + - Resource: !Sub arn:aws:s3:::${CodePipelineArtifactStoreBucket}/* + Effect: Allow + Action: + - s3:GetObject + - s3:PutObject + - s3:GetObjectVersion From e2a21a512fb1da6266351f9b6350a2db96dcf99d Mon Sep 17 00:00:00 2001 From: SudKul Date: Mon, 10 May 2021 18:12:20 +0530 Subject: [PATCH 26/56] Add Manual Deployment exercise --- examples/{ => Create_Pipeline}/buildspec.yml | 0 .../{ => Create_Pipeline}/buildspec.yml.zip | Bin .../simple-pipeline-build.yml | 0 examples/Deploy_Flask_App/Dockerfile | 11 +++++++ examples/Deploy_Flask_App/app.py | 12 +++++++ examples/Deploy_Flask_App/deployment.yml | 30 ++++++++++++++++++ 6 files changed, 53 insertions(+) rename examples/{ => Create_Pipeline}/buildspec.yml (100%) rename examples/{ => Create_Pipeline}/buildspec.yml.zip (100%) rename examples/{ => Create_Pipeline}/simple-pipeline-build.yml (100%) create mode 100644 examples/Deploy_Flask_App/Dockerfile create mode 100644 examples/Deploy_Flask_App/app.py create mode 100644 examples/Deploy_Flask_App/deployment.yml diff --git a/examples/buildspec.yml b/examples/Create_Pipeline/buildspec.yml similarity index 100% rename from examples/buildspec.yml rename to examples/Create_Pipeline/buildspec.yml diff --git a/examples/buildspec.yml.zip b/examples/Create_Pipeline/buildspec.yml.zip similarity index 100% rename from examples/buildspec.yml.zip rename to examples/Create_Pipeline/buildspec.yml.zip diff --git a/examples/simple-pipeline-build.yml b/examples/Create_Pipeline/simple-pipeline-build.yml similarity index 100% rename from examples/simple-pipeline-build.yml rename to examples/Create_Pipeline/simple-pipeline-build.yml diff --git a/examples/Deploy_Flask_App/Dockerfile b/examples/Deploy_Flask_App/Dockerfile new file mode 100644 index 0000000000..af45b00394 --- /dev/null +++ b/examples/Deploy_Flask_App/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.7.2-slim + +COPY . /app +WORKDIR /app + +RUN pip install --upgrade pip +RUN pip install flask + + +ENTRYPOINT ["python", "app.py"] + diff --git a/examples/Deploy_Flask_App/app.py b/examples/Deploy_Flask_App/app.py new file mode 100644 index 0000000000..5a42e26453 --- /dev/null +++ b/examples/Deploy_Flask_App/app.py @@ -0,0 +1,12 @@ +from flask import Flask +APP = Flask(__name__) + + +@APP.route('/') +def hello_world(): + return 'Hello, World from Flask!\n' + + + +if __name__ == '__main__': + APP.run(host='0.0.0.0', port=8080, debug=True) diff --git a/examples/Deploy_Flask_App/deployment.yml b/examples/Deploy_Flask_App/deployment.yml new file mode 100644 index 0000000000..0387862ef4 --- /dev/null +++ b/examples/Deploy_Flask_App/deployment.yml @@ -0,0 +1,30 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: simple-flask-deployment + labels: + app: simple-flask +spec: + replicas: 3 + selector: + matchLabels: + app: simple-flask + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 2 + maxSurge: 2 + template: + metadata: + labels: + app: simple-flask + spec: + containers: + - name: simple-flask + image: IMAGE_TAG + securityContext: + privileged: false + readOnlyRootFilesystem: false + allowPrivilegeEscalation: false + ports: + - containerPort: 8080 From aa81775723305cbad87e67e082053513e56a9bd4 Mon Sep 17 00:00:00 2001 From: SudKul <48475411+SudKul@users.noreply.github.com> Date: Thu, 29 Jul 2021 20:54:07 +0530 Subject: [PATCH 27/56] Update manual.yml --- .github/workflows/manual.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index e01aedfd43..a643541a7a 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -41,7 +41,7 @@ jobs: PR title: ${{ github.event.pull_request.title }} PR description: ${{ github.event.pull_request.description }} In addition, please resolve other issues, if any. - fields: '{"components": [{"name":"Github PR"}], "customfield_16449":"https://classroom.udacity.com/nanodegrees/nd0044/dashboard/overview", "customfield_16450":"Resolve the PR", "labels": ["github"]}' + fields: '{"components": [{"name":"nd0044- Full Stack Nanodegree"}], "customfield_16449":"https://classroom.udacity.com/nanodegrees/nd0044/dashboard/overview", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' - name: Log created issue run: echo "Issue ${{ steps.create.outputs.issue }} was created" From 322f6d81308bc42cbdaa2b0517510382642a23c4 Mon Sep 17 00:00:00 2001 From: rcudacity <82896433+rcudacity@users.noreply.github.com> Date: Wed, 18 Aug 2021 09:02:17 -0400 Subject: [PATCH 28/56] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ebfe63c3da..d1bd6b86e0 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Deploying a Flask API -This is the project starter repo for the fourth course in the [Udacity Full Stack Nanodegree](https://www.udacity.com/course/full-stack-web-developer-nanodegree--nd004): Server Deployment, Containerization, and Testing. +This is the project starter repo for the course Server Deployment, Containerization, and Testing. In this project you will containerize and deploy a Flask API to a Kubernetes cluster using Docker, AWS EKS, CodePipeline, and CodeBuild. @@ -35,4 +35,4 @@ Completing the project involves several steps: 5. Create a CodePipeline pipeline triggered by GitHub checkins 6. Create a CodeBuild stage which will build, test, and deploy your code -For more detail about each of these steps, see the project lesson [here](https://classroom.udacity.com/nanodegrees/nd004/parts/1d842ebf-5b10-4749-9e5e-ef28fe98f173/modules/ac13842f-c841-4c1a-b284-b47899f4613d/lessons/becb2dac-c108-4143-8f6c-11b30413e28d/concepts/092cdb35-28f7-4145-b6e6-6278b8dd7527). \ No newline at end of file +For more detail about each of these steps, see the project lesson. From 4b27e80219957f1fb0af4bc409e2a1f226f971f2 Mon Sep 17 00:00:00 2001 From: rcudacity <82896433+rcudacity@users.noreply.github.com> Date: Wed, 18 Aug 2021 14:59:11 -0400 Subject: [PATCH 29/56] Update manual.yml --- .github/workflows/manual.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index a643541a7a..068722c001 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -33,15 +33,14 @@ jobs: project: CONUPDATE issuetype: Task summary: | - Github PR - nd0044 v2 Full Stack Web Developer (refresh) | Repo: FSND-Deploy-Flask-App-to-Kubernetes-Using-EKS | PR# ${{github.event.number}} + Github PR - cd0157 Server Deployment and Containerization (Disaggregated Course) | Repo: ${{ github.repository }} | PR# ${{github.event.number}} description: | Repo link: https://github.com/${{ github.repository }} - Course name: 5. Server Deployment, Containerization and Testing PR no. ${{ github.event.pull_request.number }} PR title: ${{ github.event.pull_request.title }} PR description: ${{ github.event.pull_request.description }} In addition, please resolve other issues, if any. - fields: '{"components": [{"name":"nd0044- Full Stack Nanodegree"}], "customfield_16449":"https://classroom.udacity.com/nanodegrees/nd0044/dashboard/overview", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' + fields: '{"components": [{"name":"cd0157 - Server Deployment and Containerization (Disaggregated Course)"}], "customfield_16449":"https://classroom.udacity.com/nanodegrees/nd0044/dashboard/overview", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' - name: Log created issue run: echo "Issue ${{ steps.create.outputs.issue }} was created" From 8b8cc1dcd0276e0fd03ed2e2eeea698e750103c1 Mon Sep 17 00:00:00 2001 From: SudKul <48475411+SudKul@users.noreply.github.com> Date: Thu, 21 Oct 2021 18:54:27 +0530 Subject: [PATCH 30/56] Create CODEOWNERS --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000000..2a6bcb2832 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @udacity/active-public-content \ No newline at end of file From 40b4a985016c2fe4a2dbb47ed54c9540bb9dc2a0 Mon Sep 17 00:00:00 2001 From: Tasawar Hussain <31658686+tasawar-hussain@users.noreply.github.com> Date: Mon, 15 Nov 2021 01:35:06 +0500 Subject: [PATCH 31/56] Update ci-cd-codepipeline.cfn.yml Update python version to 3.7 for AWS::Lambda --- ci-cd-codepipeline.cfn.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-cd-codepipeline.cfn.yml b/ci-cd-codepipeline.cfn.yml index a391876ab0..14b705a580 100755 --- a/ci-cd-codepipeline.cfn.yml +++ b/ci-cd-codepipeline.cfn.yml @@ -161,7 +161,7 @@ Resources: Handler: index.handler Role: !GetAtt CustomResourceLambdaExecutionRole.Arn - Runtime: python2.7 + Runtime: python3.7 Timeout: 300 CustomResourceLambdaExecutionRole: From c97f0fd88625c625cc32057a7f49481b7313bfb5 Mon Sep 17 00:00:00 2001 From: Sudhanshu Kulshrestha <48475411+SudKul@users.noreply.github.com> Date: Wed, 11 May 2022 11:56:01 +0530 Subject: [PATCH 32/56] Update dependencies --- requirements.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 33052c2577..111531cfe5 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,9 @@ pyjwt==1.7.1 flask==1.1.2 +Jinja2<3.0.0 +MarkupSafe<2.0.0 +ruamel.yaml==0.16.5 +itsdangerous==2.0.1 +werkzeug==2.0.3 gunicorn==20.0.4 -pytest==6.2.2 +pytest==6.2.2 \ No newline at end of file From 99017530e06dcfedb4fe7259019094e15e8eaebf Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 14:59:01 +0530 Subject: [PATCH 33/56] Add starter files --- Dockerfile | 13 +++++++++++++ buildspec.yml | 3 +++ iam-role-policy.json | 8 ++++++++ trust.json | 12 ++++++++++++ 4 files changed, 36 insertions(+) create mode 100644 Dockerfile create mode 100644 iam-role-policy.json create mode 100644 trust.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..64ab97ef6a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +# Use the `python:3.7.2-slim` as a source image +FROM python:3.7.2-slim + +# Set up an app directory for your code +COPY . /app +WORKDIR /app + +# Install `pip` and needed Python packages from `requirements.txt` +RUN pip install --upgrade pip +RUN pip install -r requirements.txt + +# Define an entrypoint which will run the main app using the Gunicorn WSGI server. +ENTRYPOINT ["gunicorn", "-b", ":8080", "main:APP"] diff --git a/buildspec.yml b/buildspec.yml index fd54b14792..40503b9586 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -38,3 +38,6 @@ phases: - printf '[{"name":"simple_jwt_api","imageUri":"%s"}]' $REPOSITORY_URI:$TAG > build.json artifacts: files: build.json +env: + parameter-store: + JWT_SECRET: JWT_SECRET diff --git a/iam-role-policy.json b/iam-role-policy.json new file mode 100644 index 0000000000..b0c1222d9b --- /dev/null +++ b/iam-role-policy.json @@ -0,0 +1,8 @@ +{ + "Version": "2012-10-17", + "Statement":[{ + "Effect": "Allow", + "Action": ["eks:Describe*", "ssm:GetParameters"], + "Resource":"*" + }] +} diff --git a/trust.json b/trust.json new file mode 100644 index 0000000000..f934cf3a3f --- /dev/null +++ b/trust.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::519002666132:root" + }, + "Action": "sts:AssumeRole" + } + ] +} From c2cd2b2382a904ff9d00fdd090a984c5ef8dcfd3 Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 15:45:16 +0530 Subject: [PATCH 34/56] Update the repo name --- ci-cd-codepipeline.cfn.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-cd-codepipeline.cfn.yml b/ci-cd-codepipeline.cfn.yml index 14b705a580..c0f4d9d31b 100755 --- a/ci-cd-codepipeline.cfn.yml +++ b/ci-cd-codepipeline.cfn.yml @@ -17,7 +17,7 @@ Parameters: GitSourceRepo: Type: String Description: GitHub source repository - must contain a Dockerfile and buildspec.yml in the base - Default: FSND-Deploy-Flask-App-to-Kubernetes-Using-EKS + Default: cd0157-Server-Deployment-and-Containerization MinLength: 1 MaxLength: 100 ConstraintDescription: You must enter a GitHub repository name From 6b38e76601895198c6633415510a983e5593f8bc Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 16:23:14 +0530 Subject: [PATCH 35/56] Update the Image path --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 64ab97ef6a..ec526b0736 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ -# Use the `python:3.7.2-slim` as a source image -FROM python:3.7.2-slim +# Use the `python:3.7` as a source image from the Amazon ECR Public Gallery +# We are not using `python:3.7.2-slim` from Dockerhub because it has put a pull rate limit. +FROM public.ecr.aws/sam/build-python3.7:latest # Set up an app directory for your code COPY . /app From d0d941c36165a40f5722ee170c0945d1347bcef1 Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 16:47:17 +0530 Subject: [PATCH 36/56] Update README.md --- README.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d1bd6b86e0..d3c90f8c91 100755 --- a/README.md +++ b/README.md @@ -12,17 +12,63 @@ The Flask app that will be used for this project consists of a simple API with t The app relies on a secret set as the environment variable `JWT_SECRET` to produce a JWT. The built-in Flask server is adequate for local development, but not production, so you will be using the production-ready [Gunicorn](https://gunicorn.org/) server when deploying the app. + + +## Prerequisites + +* Docker Desktop - Installation instructions for all OSes can be found here. +* Git: Download and install Git for your system. +* Code editor: You can download and install VS code here. +* AWS Account +* Python version between 3.7 and 3.9. Check the current version using: +```bash +# Mac/Linux/Windows +python --version +``` +You can download a specific release version from here. + +* Python package manager - PIP 19.x or higher. PIP is already installed in Python 3 >=3.4 downloaded from python.org . However, you can upgrade to a specific version, say 20.2.3, using the command: +```bash +# Mac/Linux/Windows Check the current version +pip --version +# Mac/Linux +pip install --upgrade pip==20.2.3 +# Windows +python -m pip install --upgrade pip==20.2.3 +``` +* Terminal + * Mac/Linux users can use the default terminal. + * Windows users can use either the GitBash terminal or WSL. +* Command line utilities: + * AWS CLI installed and configured using the `aws configure` command. Another important configuration is the region. Do not use the us-east-1 because the cluster creation may fails mostly in us-east-1. Let's change the default region to: + ```bash + aws configure set region us-east-2 + ``` + Ensure to create all your resources in a single region. + * EKSCTL installed in your system. Follow the instructions [available here](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html#installing-eksctl) or here to download and install `eksctl` utility. + * The KUBECTL installed in your system. Installation instructions for kubectl can be found here. + + ## Initial setup -1. Fork this project to your Github account. -2. Locally clone your forked version to begin working on the project. -## Dependencies +1. Fork the Server and Deployment Containerization Github repo to your Github account. +1. Locally clone your forked version to begin working on the project. +```bash +git clone https://github.com/SudKul/cd0157-Server-Deployment-and-Containerization.git +cd cd0157-Server-Deployment-and-Containerization/ +``` +1. These are the files relevant for the current project: +```bash +. +├── main.py # Sample Flask application +├── requirements.txt # Dependencies +├── aws-auth-patch.yml # No change needed here. This is a sample file +├── buildspec.yml # No change needed here +├── ci-cd-codepipeline.cfn.yml # TODO - YAML template to create CodePipeline pipeline and CodeBuild resources +├── simple_jwt_api.yml # No change needed here +└── test_main.py +``` -- Docker Engine - - Installation instructions for all OSes can be found [here](https://docs.docker.com/install/). - - For Mac users, if you have no previous Docker Toolbox installation, you can install Docker Desktop for Mac. If you already have a Docker Toolbox installation, please read [this](https://docs.docker.com/docker-for-mac/docker-toolbox/) before installing. - - AWS Account - - You can create an AWS account by signing up [here](https://aws.amazon.com/#). ## Project Steps From 2b00b3a9324dd4f6e73c6520500769522790ed10 Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 17:27:53 +0530 Subject: [PATCH 37/56] Update aws-auth-patch.yml --- aws-auth-patch.yml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/aws-auth-patch.yml b/aws-auth-patch.yml index b6d9b9c26c..4c3b0e0f26 100644 --- a/aws-auth-patch.yml +++ b/aws-auth-patch.yml @@ -4,22 +4,18 @@ apiVersion: v1 data: mapRoles: | - - groups: - - system:masters - rolearn: arn:aws:iam::644752792305:role/UdacityFlaskDeployCBKubectlRole - username: build - groups: - system:bootstrappers - system:nodes - rolearn: arn:aws:iam::644752792305:role/eksctl-simple-jwt-api-nodegroup-n-NodeInstanceRole-17C402QC9VF6L + rolearn: arn:aws:iam::519002666132:role/eksctl-simple-jwt-api-nodegroup-n-NodeInstanceRole-1DBHED9TMYRZZ username: system:node:{{EC2PrivateDNSName}} - mapUsers: | - [] + - system:masters + rolearn: arn:aws:iam::519002666132:role/UdacityFlaskDeployCBKubectlRole + username: build kind: ConfigMap metadata: - creationTimestamp: "2021-02-26T07:40:38Z" + creationTimestamp: "2022-05-11T11:16:26Z" name: aws-auth namespace: kube-system - resourceVersion: "5992" - selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth - uid: 5bf363cb-504c-4289-93ce-74257aff0de4 + resourceVersion: "1631" + uid: 86402a4e-a9ff-4721-8c24-f0c4258f7440 From f62a9d9058b2221186fab48b94053ba00cae01bc Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 17:49:01 +0530 Subject: [PATCH 38/56] Update kubectl version --- buildspec.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 40503b9586..c7c8ee3439 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -12,11 +12,11 @@ phases: - timeout 15 sh -c "until docker info; do echo .; sleep 1; done" - curl -sS -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/bin/linux/amd64/aws-iam-authenticator # Get latest stable release kubectl - - curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl - # Command for specific kubectl version: - #- curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl + #- curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl + # Command for specific kubectl version + - curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.22.6/2022-03-09/bin/darwin/amd64/kubectl - chmod +x ./kubectl ./aws-iam-authenticator - - echo `kubectl version` + - echo `kubectl version --short --client` - export PATH=$PWD/:$PATH - python -m pip install --upgrade --force pip - apt-get update && apt-get -y install jq && pip install --upgrade awscli @@ -33,6 +33,8 @@ phases: post_build: commands: - docker push $REPOSITORY_URI:$TAG + - echo $EKS_CLUSTER_NAME + - echo $EKS_KUBECTL_ROLE_ARN - aws eks update-kubeconfig --name $EKS_CLUSTER_NAME --role-arn $EKS_KUBECTL_ROLE_ARN - kubectl apply -f simple_jwt_api.yml - printf '[{"name":"simple_jwt_api","imageUri":"%s"}]' $REPOSITORY_URI:$TAG > build.json From 22a1de64f44808a6a814efa2303b0d38ac65adb8 Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 18:01:56 +0530 Subject: [PATCH 39/56] Update kubectl version --- buildspec.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/buildspec.yml b/buildspec.yml index c7c8ee3439..95048e05ee 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -14,8 +14,9 @@ phases: # Get latest stable release kubectl #- curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl # Command for specific kubectl version - - curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.22.6/2022-03-09/bin/darwin/amd64/kubectl + - curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.22.6/2022-03-09/bin/linux/amd64/kubectl - chmod +x ./kubectl ./aws-iam-authenticator + - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin - echo `kubectl version --short --client` - export PATH=$PWD/:$PATH - python -m pip install --upgrade --force pip @@ -26,6 +27,7 @@ phases: - sed -i 's@CONTAINER_IMAGE@'"$REPOSITORY_URI:$TAG"'@' simple_jwt_api.yml - $(aws ecr get-login --no-include-email) - export KUBECONFIG=$HOME/.kube/config + - echo `ls -l` build: commands: - docker build --tag $REPOSITORY_URI:$TAG . From 94c84209143f3c09868ae8303e7090bc27ca64f4 Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 18:10:52 +0530 Subject: [PATCH 40/56] Use kubectl v1.23.6 --- buildspec.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 95048e05ee..0069010802 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -11,10 +11,12 @@ phases: - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2& - timeout 15 sh -c "until docker info; do echo .; sleep 1; done" - curl -sS -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/bin/linux/amd64/aws-iam-authenticator - # Get latest stable release kubectl - #- curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl - # Command for specific kubectl version - - curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.22.6/2022-03-09/bin/linux/amd64/kubectl + # Get latest stable release kubectl + # - curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + # You must use a kubectl version that is within one minor version difference of your Amazon EKS cluster control plane. + # For example, a 1.21 kubectl client works with Kubernetes 1.20, 1.21 and 1.22 clusters. + # For example, to download a specific version v1.23.6 on Linux, type: + - curl -LO https://dl.k8s.io/release/v1.23.6/bin/linux/amd64/kubectl - chmod +x ./kubectl ./aws-iam-authenticator - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin - echo `kubectl version --short --client` From 788446b3c299656a00d59c4d3f3ec812f83cfe36 Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 18:28:50 +0530 Subject: [PATCH 41/56] Use kubectl v1.23.6 --- buildspec.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 0069010802..2c3bed7514 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -11,16 +11,23 @@ phases: - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2& - timeout 15 sh -c "until docker info; do echo .; sleep 1; done" - curl -sS -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/bin/linux/amd64/aws-iam-authenticator - # Get latest stable release kubectl + # Download the latest stable release kubectl # - curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" # You must use a kubectl version that is within one minor version difference of your Amazon EKS cluster control plane. # For example, a 1.21 kubectl client works with Kubernetes 1.20, 1.21 and 1.22 clusters. - # For example, to download a specific version v1.23.6 on Linux, type: + # For example, to download a specific version v1.23.6 on Linux, use: - curl -LO https://dl.k8s.io/release/v1.23.6/bin/linux/amd64/kubectl + # Download the kubectl checksum file + - curl -LO "https://dl.k8s.io/v1.23.6/bin/linux/amd64/kubectl.sha256" + # Validate the kubectl binary against the checksum file + - echo "$(cat kubectl.sha256) kubectl" | sha256sum --check + # Install kubectl - chmod +x ./kubectl ./aws-iam-authenticator - - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin - - echo `kubectl version --short --client` + - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin + - echo $PATH - export PATH=$PWD/:$PATH + - echo $PATH + - echo `kubectl version --short --client` - python -m pip install --upgrade --force pip - apt-get update && apt-get -y install jq && pip install --upgrade awscli pre_build: From 29f392709602c1ca43a21af91d25195f72ebf5b9 Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 19:06:22 +0530 Subject: [PATCH 42/56] Try again --- buildspec.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 2c3bed7514..a8d08703c1 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -15,18 +15,17 @@ phases: # - curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" # You must use a kubectl version that is within one minor version difference of your Amazon EKS cluster control plane. # For example, a 1.21 kubectl client works with Kubernetes 1.20, 1.21 and 1.22 clusters. - # For example, to download a specific version v1.23.6 on Linux, use: - - curl -LO https://dl.k8s.io/release/v1.23.6/bin/linux/amd64/kubectl + # Ref: https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html OR https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ + # To download a specific version v1.22.0 on Linux, use: + - curl -LO https://dl.k8s.io/release/v1.22.0/bin/linux/amd64/kubectl # Download the kubectl checksum file - curl -LO "https://dl.k8s.io/v1.23.6/bin/linux/amd64/kubectl.sha256" # Validate the kubectl binary against the checksum file - echo "$(cat kubectl.sha256) kubectl" | sha256sum --check # Install kubectl - - chmod +x ./kubectl ./aws-iam-authenticator + - chmod +x ./kubectl ./aws-iam-authenticator - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin - - echo $PATH - - export PATH=$PWD/:$PATH - - echo $PATH + - echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc - echo `kubectl version --short --client` - python -m pip install --upgrade --force pip - apt-get update && apt-get -y install jq && pip install --upgrade awscli From df66f69d0ae414b18aa6a2241ee21062f1ab23c3 Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 19:09:46 +0530 Subject: [PATCH 43/56] Try again --- buildspec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildspec.yml b/buildspec.yml index a8d08703c1..60360c42a1 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -17,7 +17,7 @@ phases: # For example, a 1.21 kubectl client works with Kubernetes 1.20, 1.21 and 1.22 clusters. # Ref: https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html OR https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ # To download a specific version v1.22.0 on Linux, use: - - curl -LO https://dl.k8s.io/release/v1.22.0/bin/linux/amd64/kubectl + - curl -LO https://dl.k8s.io/release/v1.23.6/bin/linux/amd64/kubectl # Download the kubectl checksum file - curl -LO "https://dl.k8s.io/v1.23.6/bin/linux/amd64/kubectl.sha256" # Validate the kubectl binary against the checksum file From cea13fb72c6ebb82185a85fb77365357cd1e731c Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 19:22:14 +0530 Subject: [PATCH 44/56] Fix the path --- buildspec.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 60360c42a1..63e53d247f 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -24,8 +24,10 @@ phases: - echo "$(cat kubectl.sha256) kubectl" | sha256sum --check # Install kubectl - chmod +x ./kubectl ./aws-iam-authenticator - - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin - - echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc + # - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin + - export PATH=$PWD/:$PATH + - python --version + - echo 'export PATH=$PWD/:$PATH' >> $HOME/.bashrc - echo `kubectl version --short --client` - python -m pip install --upgrade --force pip - apt-get update && apt-get -y install jq && pip install --upgrade awscli From da7d2f6aabf92baa51c74fc50bbb4f1e869d59b2 Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 19:42:32 +0530 Subject: [PATCH 45/56] Update README.md --- README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d3c90f8c91..04a1d79c07 100755 --- a/README.md +++ b/README.md @@ -60,13 +60,17 @@ cd cd0157-Server-Deployment-and-Containerization/ 1. These are the files relevant for the current project: ```bash . -├── main.py # Sample Flask application -├── requirements.txt # Dependencies -├── aws-auth-patch.yml # No change needed here. This is a sample file -├── buildspec.yml # No change needed here -├── ci-cd-codepipeline.cfn.yml # TODO - YAML template to create CodePipeline pipeline and CodeBuild resources -├── simple_jwt_api.yml # No change needed here -└── test_main.py +├── Dockerfile +├── README.md +├── aws-auth-patch.yml +├── buildspec.yml +├── ci-cd-codepipeline.cfn.yml +├── iam-role-policy.json +├── main.py +├── requirements.txt +├── simple_jwt_api.yml +├── test_main.py +└── trust.json ``` From dc16a8683d5286223f79778b3224ede0644d6a0c Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 19:55:41 +0530 Subject: [PATCH 46/56] Add the IAM username --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 04a1d79c07..fcd5eb2e0c 100755 --- a/README.md +++ b/README.md @@ -60,11 +60,11 @@ cd cd0157-Server-Deployment-and-Containerization/ 1. These are the files relevant for the current project: ```bash . -├── Dockerfile +├── Dockerfile ├── README.md -├── aws-auth-patch.yml -├── buildspec.yml -├── ci-cd-codepipeline.cfn.yml +├── aws-auth-patch.yml #ToDo +├── buildspec.yml #ToDo +├── ci-cd-codepipeline.cfn.yml #ToDo ├── iam-role-policy.json ├── main.py ├── requirements.txt From 53b5aeef700f98d2203e2a9cb2f6b19aa8b4cb7e Mon Sep 17 00:00:00 2001 From: SudKul Date: Wed, 11 May 2022 20:04:47 +0530 Subject: [PATCH 47/56] Add the IAM username --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fcd5eb2e0c..947692587d 100755 --- a/README.md +++ b/README.md @@ -63,14 +63,14 @@ cd cd0157-Server-Deployment-and-Containerization/ ├── Dockerfile ├── README.md ├── aws-auth-patch.yml #ToDo -├── buildspec.yml #ToDo +├── buildspec.yml #ToDo ├── ci-cd-codepipeline.cfn.yml #ToDo -├── iam-role-policy.json +├── iam-role-policy.json #ToDo ├── main.py ├── requirements.txt ├── simple_jwt_api.yml -├── test_main.py -└── trust.json +├── test_main.py #ToDo +└── trust.json #ToDo ``` From a2a8fb2cdd80d83887f42ab7927dea924f35c0b3 Mon Sep 17 00:00:00 2001 From: Sudhanshu Kulshrestha <48475411+SudKul@users.noreply.github.com> Date: Wed, 11 May 2022 20:17:37 +0530 Subject: [PATCH 48/56] Update the starter code (#41) --- Dockerfile | 14 ++++++++ README.md | 66 +++++++++++++++++++++++++++++++++----- aws-auth-patch.yml | 18 ++++------- buildspec.yml | 31 ++++++++++++++---- ci-cd-codepipeline.cfn.yml | 2 +- iam-role-policy.json | 8 +++++ requirements.txt | 7 +++- trust.json | 12 +++++++ 8 files changed, 130 insertions(+), 28 deletions(-) create mode 100644 Dockerfile create mode 100644 iam-role-policy.json create mode 100644 trust.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..ec526b0736 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +# Use the `python:3.7` as a source image from the Amazon ECR Public Gallery +# We are not using `python:3.7.2-slim` from Dockerhub because it has put a pull rate limit. +FROM public.ecr.aws/sam/build-python3.7:latest + +# Set up an app directory for your code +COPY . /app +WORKDIR /app + +# Install `pip` and needed Python packages from `requirements.txt` +RUN pip install --upgrade pip +RUN pip install -r requirements.txt + +# Define an entrypoint which will run the main app using the Gunicorn WSGI server. +ENTRYPOINT ["gunicorn", "-b", ":8080", "main:APP"] diff --git a/README.md b/README.md index d1bd6b86e0..947692587d 100755 --- a/README.md +++ b/README.md @@ -12,17 +12,67 @@ The Flask app that will be used for this project consists of a simple API with t The app relies on a secret set as the environment variable `JWT_SECRET` to produce a JWT. The built-in Flask server is adequate for local development, but not production, so you will be using the production-ready [Gunicorn](https://gunicorn.org/) server when deploying the app. + + +## Prerequisites + +* Docker Desktop - Installation instructions for all OSes can be found here. +* Git: Download and install Git for your system. +* Code editor: You can download and install VS code here. +* AWS Account +* Python version between 3.7 and 3.9. Check the current version using: +```bash +# Mac/Linux/Windows +python --version +``` +You can download a specific release version from here. + +* Python package manager - PIP 19.x or higher. PIP is already installed in Python 3 >=3.4 downloaded from python.org . However, you can upgrade to a specific version, say 20.2.3, using the command: +```bash +# Mac/Linux/Windows Check the current version +pip --version +# Mac/Linux +pip install --upgrade pip==20.2.3 +# Windows +python -m pip install --upgrade pip==20.2.3 +``` +* Terminal + * Mac/Linux users can use the default terminal. + * Windows users can use either the GitBash terminal or WSL. +* Command line utilities: + * AWS CLI installed and configured using the `aws configure` command. Another important configuration is the region. Do not use the us-east-1 because the cluster creation may fails mostly in us-east-1. Let's change the default region to: + ```bash + aws configure set region us-east-2 + ``` + Ensure to create all your resources in a single region. + * EKSCTL installed in your system. Follow the instructions [available here](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html#installing-eksctl) or here to download and install `eksctl` utility. + * The KUBECTL installed in your system. Installation instructions for kubectl can be found here. + + ## Initial setup -1. Fork this project to your Github account. -2. Locally clone your forked version to begin working on the project. -## Dependencies +1. Fork the Server and Deployment Containerization Github repo to your Github account. +1. Locally clone your forked version to begin working on the project. +```bash +git clone https://github.com/SudKul/cd0157-Server-Deployment-and-Containerization.git +cd cd0157-Server-Deployment-and-Containerization/ +``` +1. These are the files relevant for the current project: +```bash +. +├── Dockerfile +├── README.md +├── aws-auth-patch.yml #ToDo +├── buildspec.yml #ToDo +├── ci-cd-codepipeline.cfn.yml #ToDo +├── iam-role-policy.json #ToDo +├── main.py +├── requirements.txt +├── simple_jwt_api.yml +├── test_main.py #ToDo +└── trust.json #ToDo +``` -- Docker Engine - - Installation instructions for all OSes can be found [here](https://docs.docker.com/install/). - - For Mac users, if you have no previous Docker Toolbox installation, you can install Docker Desktop for Mac. If you already have a Docker Toolbox installation, please read [this](https://docs.docker.com/docker-for-mac/docker-toolbox/) before installing. - - AWS Account - - You can create an AWS account by signing up [here](https://aws.amazon.com/#). ## Project Steps diff --git a/aws-auth-patch.yml b/aws-auth-patch.yml index b6d9b9c26c..4c3b0e0f26 100644 --- a/aws-auth-patch.yml +++ b/aws-auth-patch.yml @@ -4,22 +4,18 @@ apiVersion: v1 data: mapRoles: | - - groups: - - system:masters - rolearn: arn:aws:iam::644752792305:role/UdacityFlaskDeployCBKubectlRole - username: build - groups: - system:bootstrappers - system:nodes - rolearn: arn:aws:iam::644752792305:role/eksctl-simple-jwt-api-nodegroup-n-NodeInstanceRole-17C402QC9VF6L + rolearn: arn:aws:iam::519002666132:role/eksctl-simple-jwt-api-nodegroup-n-NodeInstanceRole-1DBHED9TMYRZZ username: system:node:{{EC2PrivateDNSName}} - mapUsers: | - [] + - system:masters + rolearn: arn:aws:iam::519002666132:role/UdacityFlaskDeployCBKubectlRole + username: build kind: ConfigMap metadata: - creationTimestamp: "2021-02-26T07:40:38Z" + creationTimestamp: "2022-05-11T11:16:26Z" name: aws-auth namespace: kube-system - resourceVersion: "5992" - selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth - uid: 5bf363cb-504c-4289-93ce-74257aff0de4 + resourceVersion: "1631" + uid: 86402a4e-a9ff-4721-8c24-f0c4258f7440 diff --git a/buildspec.yml b/buildspec.yml index fd54b14792..63e53d247f 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -11,13 +11,24 @@ phases: - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2& - timeout 15 sh -c "until docker info; do echo .; sleep 1; done" - curl -sS -o aws-iam-authenticator https://amazon-eks.s3-us-west-2.amazonaws.com/1.10.3/2018-07-26/bin/linux/amd64/aws-iam-authenticator - # Get latest stable release kubectl - - curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl - # Command for specific kubectl version: - #- curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl - - chmod +x ./kubectl ./aws-iam-authenticator - - echo `kubectl version` - - export PATH=$PWD/:$PATH + # Download the latest stable release kubectl + # - curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + # You must use a kubectl version that is within one minor version difference of your Amazon EKS cluster control plane. + # For example, a 1.21 kubectl client works with Kubernetes 1.20, 1.21 and 1.22 clusters. + # Ref: https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html OR https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ + # To download a specific version v1.22.0 on Linux, use: + - curl -LO https://dl.k8s.io/release/v1.23.6/bin/linux/amd64/kubectl + # Download the kubectl checksum file + - curl -LO "https://dl.k8s.io/v1.23.6/bin/linux/amd64/kubectl.sha256" + # Validate the kubectl binary against the checksum file + - echo "$(cat kubectl.sha256) kubectl" | sha256sum --check + # Install kubectl + - chmod +x ./kubectl ./aws-iam-authenticator + # - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin + - export PATH=$PWD/:$PATH + - python --version + - echo 'export PATH=$PWD/:$PATH' >> $HOME/.bashrc + - echo `kubectl version --short --client` - python -m pip install --upgrade --force pip - apt-get update && apt-get -y install jq && pip install --upgrade awscli pre_build: @@ -26,6 +37,7 @@ phases: - sed -i 's@CONTAINER_IMAGE@'"$REPOSITORY_URI:$TAG"'@' simple_jwt_api.yml - $(aws ecr get-login --no-include-email) - export KUBECONFIG=$HOME/.kube/config + - echo `ls -l` build: commands: - docker build --tag $REPOSITORY_URI:$TAG . @@ -33,8 +45,13 @@ phases: post_build: commands: - docker push $REPOSITORY_URI:$TAG + - echo $EKS_CLUSTER_NAME + - echo $EKS_KUBECTL_ROLE_ARN - aws eks update-kubeconfig --name $EKS_CLUSTER_NAME --role-arn $EKS_KUBECTL_ROLE_ARN - kubectl apply -f simple_jwt_api.yml - printf '[{"name":"simple_jwt_api","imageUri":"%s"}]' $REPOSITORY_URI:$TAG > build.json artifacts: files: build.json +env: + parameter-store: + JWT_SECRET: JWT_SECRET diff --git a/ci-cd-codepipeline.cfn.yml b/ci-cd-codepipeline.cfn.yml index 14b705a580..c0f4d9d31b 100755 --- a/ci-cd-codepipeline.cfn.yml +++ b/ci-cd-codepipeline.cfn.yml @@ -17,7 +17,7 @@ Parameters: GitSourceRepo: Type: String Description: GitHub source repository - must contain a Dockerfile and buildspec.yml in the base - Default: FSND-Deploy-Flask-App-to-Kubernetes-Using-EKS + Default: cd0157-Server-Deployment-and-Containerization MinLength: 1 MaxLength: 100 ConstraintDescription: You must enter a GitHub repository name diff --git a/iam-role-policy.json b/iam-role-policy.json new file mode 100644 index 0000000000..b0c1222d9b --- /dev/null +++ b/iam-role-policy.json @@ -0,0 +1,8 @@ +{ + "Version": "2012-10-17", + "Statement":[{ + "Effect": "Allow", + "Action": ["eks:Describe*", "ssm:GetParameters"], + "Resource":"*" + }] +} diff --git a/requirements.txt b/requirements.txt index 33052c2577..111531cfe5 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,9 @@ pyjwt==1.7.1 flask==1.1.2 +Jinja2<3.0.0 +MarkupSafe<2.0.0 +ruamel.yaml==0.16.5 +itsdangerous==2.0.1 +werkzeug==2.0.3 gunicorn==20.0.4 -pytest==6.2.2 +pytest==6.2.2 \ No newline at end of file diff --git a/trust.json b/trust.json new file mode 100644 index 0000000000..f934cf3a3f --- /dev/null +++ b/trust.json @@ -0,0 +1,12 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::519002666132:root" + }, + "Action": "sts:AssumeRole" + } + ] +} From bbf099c44fe9c9edeade0e1af712d17c0608e6a4 Mon Sep 17 00:00:00 2001 From: SudKul Date: Sat, 14 May 2022 23:27:06 +0530 Subject: [PATCH 49/56] Add CFN templates --- examples/Cloudformation/my_parameters.json | 14 +++++++ examples/Cloudformation/template_EC2.yml | 46 ++++++++++++++++++++++ examples/Cloudformation/template_VPN.yml | 11 ++++++ examples/Deploy_Flask_App/deployment.yml | 3 +- 4 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 examples/Cloudformation/my_parameters.json create mode 100644 examples/Cloudformation/template_EC2.yml create mode 100644 examples/Cloudformation/template_VPN.yml diff --git a/examples/Cloudformation/my_parameters.json b/examples/Cloudformation/my_parameters.json new file mode 100644 index 0000000000..97660b431c --- /dev/null +++ b/examples/Cloudformation/my_parameters.json @@ -0,0 +1,14 @@ +[ + { + "ParameterKey": "myVPC", + "ParameterValue": "vpc-098defbc811aad87c" + }, + { + "ParameterKey": "PublicSubnet", + "ParameterValue": "subnet-031d7c02210432b1c" + }, + { + "ParameterKey": "AMItoUse", + "ParameterValue": "ami-0fa49cc9dc8d62c84" + } +] \ No newline at end of file diff --git a/examples/Cloudformation/template_EC2.yml b/examples/Cloudformation/template_EC2.yml new file mode 100644 index 0000000000..cc104b9929 --- /dev/null +++ b/examples/Cloudformation/template_EC2.yml @@ -0,0 +1,46 @@ +Parameters: + myVPC: + Description: VPC used to deploy our resources below + Type: AWS::EC2::VPC::Id + PublicSubnet: + Description: Subnet to be used for our Web Server + Type: AWS::EC2::Subnet::Id + AMItoUse: + Description: AMI to use for our base image + Type: String +Resources: + myWebAccessSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Allow http to our test host + VpcId: + Ref: myVPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + SecurityGroupEgress: + - IpProtocol: -1 + FromPort: -1 + ToPort: -1 + CidrIp: 0.0.0.0/0 + myWebServerInstance: + Type: AWS::EC2::Instance + Properties: + InstanceType: t3.micro + ImageId: !Ref AMItoUse + NetworkInterfaces: + - AssociatePublicIpAddress: "true" + DeviceIndex: "0" + GroupSet: + - Ref: "myWebAccessSecurityGroup" + SubnetId: + Ref: "PublicSubnet" + UserData: + Fn::Base64: !Sub | + #!/bin/bash + sudo yum update -y + sudo yum install -y httpd + sudo systemctl start httpd + sudo systemctl enable httpd \ No newline at end of file diff --git a/examples/Cloudformation/template_VPN.yml b/examples/Cloudformation/template_VPN.yml new file mode 100644 index 0000000000..14324ad508 --- /dev/null +++ b/examples/Cloudformation/template_VPN.yml @@ -0,0 +1,11 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Udacity - This template deploys a Virtual Private Network +Resources: + UdacityVPC: + Type: 'AWS::EC2::VPC' + Properties: + CidrBlock: 10.0.0.0/16 + EnableDnsHostnames: 'true' + Tags: + - Key: name + Value: myfirsttestvpc \ No newline at end of file diff --git a/examples/Deploy_Flask_App/deployment.yml b/examples/Deploy_Flask_App/deployment.yml index 0387862ef4..202f84ba87 100644 --- a/examples/Deploy_Flask_App/deployment.yml +++ b/examples/Deploy_Flask_App/deployment.yml @@ -21,7 +21,8 @@ spec: spec: containers: - name: simple-flask - image: IMAGE_TAG + # image: IMAGE_TAG + image: sudkul/simple-flask securityContext: privileged: false readOnlyRootFilesystem: false From 997a581dd3aa95010ab99a5a148ad5bdf1050dc1 Mon Sep 17 00:00:00 2001 From: Sudhanshu Kulshrestha <48475411+SudKul@users.noreply.github.com> Date: Sat, 14 May 2022 23:30:44 +0530 Subject: [PATCH 50/56] Update manual.yml --- .github/workflows/manual.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/manual.yml b/.github/workflows/manual.yml index 068722c001..27d15f879d 100644 --- a/.github/workflows/manual.yml +++ b/.github/workflows/manual.yml @@ -33,14 +33,14 @@ jobs: project: CONUPDATE issuetype: Task summary: | - Github PR - cd0157 Server Deployment and Containerization (Disaggregated Course) | Repo: ${{ github.repository }} | PR# ${{github.event.number}} + Github PR - nd0044 - Full Stack Nanodegree C4 | Repo: ${{ github.repository }} | PR# ${{github.event.number}} description: | Repo link: https://github.com/${{ github.repository }} PR no. ${{ github.event.pull_request.number }} PR title: ${{ github.event.pull_request.title }} PR description: ${{ github.event.pull_request.description }} In addition, please resolve other issues, if any. - fields: '{"components": [{"name":"cd0157 - Server Deployment and Containerization (Disaggregated Course)"}], "customfield_16449":"https://classroom.udacity.com/nanodegrees/nd0044/dashboard/overview", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' + fields: '{"components": [{"name":"nd0044 - Full Stack Nanodegree"}], "customfield_16449":"https://classroom.udacity.com/nanodegrees/nd0044/dashboard/overview", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' - name: Log created issue run: echo "Issue ${{ steps.create.outputs.issue }} was created" From 35017a71242b4a099bc9da6a3a1f5a27a27e05c3 Mon Sep 17 00:00:00 2001 From: Daniel Abrao Date: Sun, 31 Mar 2024 16:45:09 -0300 Subject: [PATCH 51/56] Replace requests lib from botocore with urllib3 --- ci-cd-codepipeline.cfn.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ci-cd-codepipeline.cfn.yml b/ci-cd-codepipeline.cfn.yml index c0f4d9d31b..fe24d6140a 100755 --- a/ci-cd-codepipeline.cfn.yml +++ b/ci-cd-codepipeline.cfn.yml @@ -119,7 +119,7 @@ Resources: ZipFile: | import json import boto3 - from botocore.vendored import requests + import urllib3 def handler(event, context): response = { 'Status': 'SUCCESS', @@ -130,7 +130,8 @@ Resources: 'LogicalResourceId': event['LogicalResourceId'], 'Data': {"Message": "Resource creation successful!"}, } - + + http = urllib3.PoolManager() client = boto3.client('iam') try: if event['RequestType'] == 'Create': @@ -155,13 +156,16 @@ Resources: response['Data'] = {"Message": "Resource creation failed"} response_body = json.dumps(response) - headers = {'content-type': '', "content-length": str(len(response_body)) } - put_response = requests.put(event['ResponseURL'], headers=headers, data=response_body) + headers = {'Content-Type': 'application/json', "content-length": str(len(response_body)) } + put_response = http.request('PUT', + event['ResponseURL'], + body = response_body, + headers=headers) return response Handler: index.handler Role: !GetAtt CustomResourceLambdaExecutionRole.Arn - Runtime: python3.7 + Runtime: python3.9 Timeout: 300 CustomResourceLambdaExecutionRole: From 0b62832266e6b013da9dcaab9d36f75ded977c45 Mon Sep 17 00:00:00 2001 From: Daniel Abrao Date: Sun, 31 Mar 2024 16:46:58 -0300 Subject: [PATCH 52/56] Replace dl.k8s.io with AWS image source --- buildspec.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 63e53d247f..06c310ee4d 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -16,12 +16,12 @@ phases: # You must use a kubectl version that is within one minor version difference of your Amazon EKS cluster control plane. # For example, a 1.21 kubectl client works with Kubernetes 1.20, 1.21 and 1.22 clusters. # Ref: https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html OR https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ - # To download a specific version v1.22.0 on Linux, use: - - curl -LO https://dl.k8s.io/release/v1.23.6/bin/linux/amd64/kubectl + # To download a specific version v1.27.9 on Linux, use: + - curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.27.9/2024-01-04/bin/linux/amd64/kubectl # Download the kubectl checksum file - - curl -LO "https://dl.k8s.io/v1.23.6/bin/linux/amd64/kubectl.sha256" + - curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.27.9/2024-01-04/bin/linux/amd64/kubectl.sha256 # Validate the kubectl binary against the checksum file - - echo "$(cat kubectl.sha256) kubectl" | sha256sum --check + - sha256sum -c kubectl.sha256 # Install kubectl - chmod +x ./kubectl ./aws-iam-authenticator # - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin From ce316b5f25a394778b253816249ec664ef5283b2 Mon Sep 17 00:00:00 2001 From: Daniel Abrao Date: Sun, 31 Mar 2024 16:47:24 -0300 Subject: [PATCH 53/56] Update google signing key --- buildspec.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/buildspec.yml b/buildspec.yml index 06c310ee4d..575e8322fa 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -30,7 +30,8 @@ phases: - echo 'export PATH=$PWD/:$PATH' >> $HOME/.bashrc - echo `kubectl version --short --client` - python -m pip install --upgrade --force pip - - apt-get update && apt-get -y install jq && pip install --upgrade awscli + - wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add + - apt-get update && apt-get -y install jq && pip install --upgrade awscli pytest pre_build: commands: - TAG="$REPOSITORY_NAME.$REPOSITORY_BRANCH.$ENVIRONMENT_NAME.$(date +%Y-%m-%d.%H.%M.%S).$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)" From 2ab472d7058c31d9106620a6eee7773b7c6994c2 Mon Sep 17 00:00:00 2001 From: Daniel Abrao Date: Sun, 31 Mar 2024 16:47:43 -0300 Subject: [PATCH 54/56] Execute pip install to avoid issues within testing --- buildspec.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/buildspec.yml b/buildspec.yml index 575e8322fa..db3de3995d 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -33,12 +33,13 @@ phases: - wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - apt-get update && apt-get -y install jq && pip install --upgrade awscli pytest pre_build: - commands: - - TAG="$REPOSITORY_NAME.$REPOSITORY_BRANCH.$ENVIRONMENT_NAME.$(date +%Y-%m-%d.%H.%M.%S).$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)" - - sed -i 's@CONTAINER_IMAGE@'"$REPOSITORY_URI:$TAG"'@' simple_jwt_api.yml - - $(aws ecr get-login --no-include-email) - - export KUBECONFIG=$HOME/.kube/config - - echo `ls -l` + commands: + - TAG="$REPOSITORY_NAME.$REPOSITORY_BRANCH.$ENVIRONMENT_NAME.$(date +%Y-%m-%d.%H.%M.%S).$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)" + - sed -i 's@CONTAINER_IMAGE@'"$REPOSITORY_URI:$TAG"'@' simple_jwt_api.yml + - $(aws ecr get-login --no-include-email) + - export KUBECONFIG=$HOME/.kube/config + - echo `ls -l` + - pip install -r requirements.txt build: commands: - docker build --tag $REPOSITORY_URI:$TAG . From a996e819da9deab8263d4679c54e3aa4935731ec Mon Sep 17 00:00:00 2001 From: Daniel Abrao Date: Sun, 31 Mar 2024 16:58:37 -0300 Subject: [PATCH 55/56] Update Dockerfile base image --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index ec526b0736..6972c73b1b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -# Use the `python:3.7` as a source image from the Amazon ECR Public Gallery -# We are not using `python:3.7.2-slim` from Dockerhub because it has put a pull rate limit. -FROM public.ecr.aws/sam/build-python3.7:latest +# Use the `python:3.9` as a source image from the Amazon ECR Public Gallery +# We are not using `python:3.7.2-slim` from Dockerhub because it has put a pull rate limit. +FROM public.ecr.aws/sam/build-python3.9:latest # Set up an app directory for your code COPY . /app From 7a0a7bfd87bdbc6da7a2de2ac1d5c0c4697a184c Mon Sep 17 00:00:00 2001 From: "DESKTOP-RNK2HL9\\DELL" Date: Tue, 24 Dec 2024 01:14:38 +0700 Subject: [PATCH 56/56] update code --- README.md | 51 ++++++++++++++++++++------------------ aws-auth-patch.yml | 25 ++++++++----------- aws-auth.patch.json | 11 ++++++++ aws-auth.yaml | 0 ci-cd-codepipeline.cfn.yml | 21 ++++++---------- config | 11 ++++++++ fake-ca-file | 1 + mypv.yml | 11 ++++++++ pvc.yml | 10 ++++++++ trust.json | 20 +++++++-------- 10 files changed, 99 insertions(+), 62 deletions(-) create mode 100644 aws-auth.patch.json create mode 100644 aws-auth.yaml create mode 100644 config create mode 100644 fake-ca-file create mode 100644 mypv.yml create mode 100644 pvc.yml diff --git a/README.md b/README.md index 947692587d..34efd6ab75 100755 --- a/README.md +++ b/README.md @@ -6,28 +6,29 @@ In this project you will containerize and deploy a Flask API to a Kubernetes clu The Flask app that will be used for this project consists of a simple API with three endpoints: -- `GET '/'`: This is a simple health check, which returns the response 'Healthy'. +- `GET '/'`: This is a simple health check, which returns the response 'Healthy'. - `POST '/auth'`: This takes a email and password as json arguments and returns a JWT based on a custom secret. -- `GET '/contents'`: This requires a valid JWT, and returns the un-encrpyted contents of that token. +- `GET '/contents'`: This requires a valid JWT, and returns the un-encrpyted contents of that token. The app relies on a secret set as the environment variable `JWT_SECRET` to produce a JWT. The built-in Flask server is adequate for local development, but not production, so you will be using the production-ready [Gunicorn](https://gunicorn.org/) server when deploying the app. - - ## Prerequisites -* Docker Desktop - Installation instructions for all OSes can be found here. -* Git: Download and install Git for your system. -* Code editor: You can download and install VS code here. -* AWS Account -* Python version between 3.7 and 3.9. Check the current version using: +- Docker Desktop - Installation instructions for all OSes can be found here. +- Git: Download and install Git for your system. +- Code editor: You can download and install VS code here. +- AWS Account +- Python version between 3.7 and 3.9. Check the current version using: + ```bash -# Mac/Linux/Windows +# Mac/Linux/Windows python --version ``` + You can download a specific release version from here. -* Python package manager - PIP 19.x or higher. PIP is already installed in Python 3 >=3.4 downloaded from python.org . However, you can upgrade to a specific version, say 20.2.3, using the command: +- Python package manager - PIP 19.x or higher. PIP is already installed in Python 3 >=3.4 downloaded from python.org . However, you can upgrade to a specific version, say 20.2.3, using the command: + ```bash # Mac/Linux/Windows Check the current version pip --version @@ -36,31 +37,34 @@ pip install --upgrade pip==20.2.3 # Windows python -m pip install --upgrade pip==20.2.3 ``` -* Terminal - * Mac/Linux users can use the default terminal. - * Windows users can use either the GitBash terminal or WSL. -* Command line utilities: - * AWS CLI installed and configured using the `aws configure` command. Another important configuration is the region. Do not use the us-east-1 because the cluster creation may fails mostly in us-east-1. Let's change the default region to: + +- Terminal + - Mac/Linux users can use the default terminal. + - Windows users can use either the GitBash terminal or WSL. +- Command line utilities: + - AWS CLI installed and configured using the `aws configure` command. Another important configuration is the region. Do not use the us-east-1 because the cluster creation may fails mostly in us-east-1. Let's change the default region to: ```bash - aws configure set region us-east-2 + aws configure set region us-east-2 ``` - Ensure to create all your resources in a single region. - * EKSCTL installed in your system. Follow the instructions [available here](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html#installing-eksctl) or here to download and install `eksctl` utility. - * The KUBECTL installed in your system. Installation instructions for kubectl can be found here. - + Ensure to create all your resources in a single region. + - EKSCTL installed in your system. Follow the instructions [available here](https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html#installing-eksctl) or here to download and install `eksctl` utility. + - The KUBECTL installed in your system. Installation instructions for kubectl can be found here. ## Initial setup 1. Fork the Server and Deployment Containerization Github repo to your Github account. 1. Locally clone your forked version to begin working on the project. + ```bash git clone https://github.com/SudKul/cd0157-Server-Deployment-and-Containerization.git cd cd0157-Server-Deployment-and-Containerization/ ``` + 1. These are the files relevant for the current project: + ```bash . -├── Dockerfile +├── Dockerfile ├── README.md ├── aws-auth-patch.yml #ToDo ├── buildspec.yml #ToDo @@ -70,10 +74,9 @@ cd cd0157-Server-Deployment-and-Containerization/ ├── requirements.txt ├── simple_jwt_api.yml ├── test_main.py #ToDo -└── trust.json #ToDo +└── trust.json #ToDo ``` - ## Project Steps Completing the project involves several steps: diff --git a/aws-auth-patch.yml b/aws-auth-patch.yml index 4c3b0e0f26..de96fee422 100644 --- a/aws-auth-patch.yml +++ b/aws-auth-patch.yml @@ -1,21 +1,16 @@ -# This is a sample aws-auth-patch.yml file. -# Actual aws-auth-patch.yml will be created at /System/Volumes/Data/private/tmp/aws-auth-patch.yml path. - apiVersion: v1 +kind: ConfigMap +metadata: + name: aws-auth + namespace: kube-system data: mapRoles: | - groups: - - system:bootstrappers - - system:nodes - rolearn: arn:aws:iam::519002666132:role/eksctl-simple-jwt-api-nodegroup-n-NodeInstanceRole-1DBHED9TMYRZZ + - system:bootstrappers + - system:nodes + rolearn: arn:aws:iam::672636165283:role/eksctl-simple-jwt-api3-nodegroup-n-NodeInstanceRole-iZj7nkJ0suwx username: system:node:{{EC2PrivateDNSName}} - - system:masters - rolearn: arn:aws:iam::519002666132:role/UdacityFlaskDeployCBKubectlRole + - groups: + - system:masters + rolearn: arn:aws:iam::672636165283:role/UdacityFlaskDeployCBKubectlRole username: build -kind: ConfigMap -metadata: - creationTimestamp: "2022-05-11T11:16:26Z" - name: aws-auth - namespace: kube-system - resourceVersion: "1631" - uid: 86402a4e-a9ff-4721-8c24-f0c4258f7440 diff --git a/aws-auth.patch.json b/aws-auth.patch.json new file mode 100644 index 0000000000..fe372e4ac1 --- /dev/null +++ b/aws-auth.patch.json @@ -0,0 +1,11 @@ +{ + "apiVersion": "v1", + "data": { + "mapRoles": " - groups:\n - system:bootstrappers\n - system:nodes\n rolearn: arn:aws:iam::672636165283:role/eksctl-simple-jwt-api3-nodegroup-n-NodeInstanceRole-iZj7nkJ0suwx\n username: system:node:{{EC2PrivateDNSName}}\n - groups:\n - system:masters\n rolearn: arn:aws:iam::672636165283:role/UdacityFlaskDeployCBKubectlRole\n username: build" + }, + "kind": "ConfigMap", + "metadata": { + "name": "aws-auth", + "namespace": "kube-system" + } +} diff --git a/aws-auth.yaml b/aws-auth.yaml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ci-cd-codepipeline.cfn.yml b/ci-cd-codepipeline.cfn.yml index fe24d6140a..f4cfeea5eb 100755 --- a/ci-cd-codepipeline.cfn.yml +++ b/ci-cd-codepipeline.cfn.yml @@ -3,13 +3,11 @@ AWSTemplateFormatVersion: 2010-09-09 Description: EKSWSV1 - Parameters: - EksClusterName: Type: String Description: The name of the EKS cluster created - Default: simple-jwt-api + Default: simple-jwt-api3 MinLength: 1 MaxLength: 100 ConstraintDescription: You must enter the EKS cluster name @@ -40,7 +38,7 @@ Parameters: GitHubUser: Type: String - Default: SudKul + Default: ChinhQuoc Description: GitHub username or organization MinLength: 3 MaxLength: 100 @@ -62,7 +60,6 @@ Parameters: MaxLength: 100 ConstraintDescription: You must enter a kubectl IAM role - Metadata: AWS::CloudFormation::Interface: ParameterGroups: @@ -101,9 +98,7 @@ Metadata: EksClusterName: default: EKS cluster name - Resources: - EcrDockerRepository: Type: AWS::ECR::Repository DeletionPolicy: Retain @@ -130,7 +125,7 @@ Resources: 'LogicalResourceId': event['LogicalResourceId'], 'Data': {"Message": "Resource creation successful!"}, } - + http = urllib3.PoolManager() client = boto3.client('iam') try: @@ -260,25 +255,25 @@ Resources: Effect: Allow Action: - sts:AssumeRole - - Resource: '*' + - Resource: "*" Effect: Allow Action: - eks:Describe* - - Resource: '*' + - Resource: "*" Effect: Allow Action: - ssm:GetParameters - - Resource: '*' + - Resource: "*" Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - - Resource: '*' + - Resource: "*" Effect: Allow Action: - ecr:GetAuthorizationToken - - Resource: '*' + - Resource: "*" Effect: Allow Action: - ec2:CreateNetworkInterface diff --git a/config b/config new file mode 100644 index 0000000000..31f955e001 --- /dev/null +++ b/config @@ -0,0 +1,11 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority: fake-ca-file + server: https://7C0C739CE282E44638066B74C876E36D.gr7.us-east-2.eks.amazonaws.com + name: simple-jwt-api +contexts: null +current-context: "" +kind: Config +preferences: {} +users: null diff --git a/fake-ca-file b/fake-ca-file new file mode 100644 index 0000000000..0a08f39f7a --- /dev/null +++ b/fake-ca-file @@ -0,0 +1 @@ +LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJVTgwTjZGUTFVMWN3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TkRFeE1qY3hNREV6TURCYUZ3MHpOREV4TWpVeE1ERTRNREJhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUUROeTVWSXF5NkF6aHFrcDlMeVN3ZWNYd1J1MlNRZEljZlVacVZZanVDSEVxa2JhbDFTUDF6eWl6R08KVjRNdlpoTnI0QzR6cGxtRXUrcDFDczQ2NlpqOTlNUEU5dm1MNjE2emh5ckRkMDdsRHdKUXlicm9ZcUcreXVNeAp1N0Z4bW8zY2xBMjhWWHFSYXJ2UzNVUldmYVhFd1F2UzYzc09lem9TcWEzLzhYb1RhUjgzd2k1bmdZcFl5R1VoClNwTS9oTDRIanRDUXY5cU02R201Z3dIN1o2VmZpL0xER3BtSVNzOGkvTlJPcjBaRjFuRHQzRHM5R3JTS3RPbjQKcjJwRjAvUmRtMjlUb3ZwUU5nbEQwSUVtVncrcmwxcnRIYmYyemViQWxsbmw2cm9FR2h5OTliL0tjc2RMOVhZVApwZy9KeENCRkhFcDNLdCtjOGdQandHYjcrNVJIQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJUVGJ2dmNObXIyZFZwVEVKdlJGSklHSVFmWXdEQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQkU1dW1sSDVhYwpzUXAyQ3YvVUc4MzBmOWNpZC8wUEs0RStoOWJ1aUJyVWc0WjYvb2NEelFNbVV5eStOem5IWmgrTUVuVzAzNHd6CnlMU0QwOVdyS3dwaGxFMWVZTlZBeGpXeXo5cm1BRDY0eTdWMksxaHJVSk9Nb3ppc2RVUU0veS81d2hMWUlJWEQKZkxTUUVIaUZMdFI0d1ZkcmN1Y2tzZXA4UVVOcmRGNmVONUtvNUdzQlJZTnhvNWk3Q21GOHRYeCt1TzBxOXBhVgprK2sxRkJlT0plcFF5MHB3bkhKWTFNSnUzRGhib0s1dzJ6OHBRYUwzc1hVdTZsQjV4UjB6bTBZQTRteitHTXJTCjBsSFk4ZWpaT08rTGQ0S1FNNTc0b2hxWlYwV3JLVnM2TFd6WWZaRUVjN0xTZmFlMVYrZ1BJbEQvcGY5dE1Tbm0KSDdKb0lpa0ZuOFlHCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K \ No newline at end of file diff --git a/mypv.yml b/mypv.yml new file mode 100644 index 0000000000..f9c5b6fafa --- /dev/null +++ b/mypv.yml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: my-pv +spec: + capacity: + storage: 5Gi # Specify the size of the volume + accessModes: + - ReadWriteOnce # Specify the access mode + hostPath: # This is for local development; change it for production + path: /mnt/data # Path on the host machine diff --git a/pvc.yml b/pvc.yml new file mode 100644 index 0000000000..870d465e4a --- /dev/null +++ b/pvc.yml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: my-pvc +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi # This should match or be less than the PV capacity diff --git a/trust.json b/trust.json index f934cf3a3f..380b952b82 100644 --- a/trust.json +++ b/trust.json @@ -1,12 +1,12 @@ { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "AWS": "arn:aws:iam::519002666132:root" - }, - "Action": "sts:AssumeRole" - } - ] + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::672636165283:root" + }, + "Action": "sts:AssumeRole" + } + ] }