J'ai configuré une paire passerelle/aws lambda d'api avec AWS sam local et j'ai confirmé que je pouvais l'appeler avec succès après l'exécution.
sam local start-api
J'ai ensuite ajouté une instance locale de dynamodb dans un conteneur de menu fixe et créé une table à l'aide de la clé aws
Mais, après avoir ajouté le code au lambda pour écrire dans l’instance dynamodb, je reçois:
2018-02-22T11: 13: 16.172Z erreur ed9ab38e-fb54-18a4-0852-db7e5b56c8cd: n'a pas pu écrire dans la table: {"message": "connect ECONNREFUSED 0.0.0.0:8000","code":"NetworkingError","errno":"ECONNREFUSED","syscall":"connect", adresse ":" 0.0.0.0 "," port ": 8000," region ":" eu-west-2 "," nom ordinateur ":" 0.0.0.0 "," réessayable ": true," heure ":" 2018-02 -22T11: 13: 16.165Z "} écriture de l'événement à partir de la commande: {"name": "test", "géolocalisation": "xyz", "type": "createDestination"} END ID requête: ed9ab38e-fb54-18a4-0852-db7e5b56c8cd
J'ai constaté en ligne que vous deviez peut-être vous connecter au même réseau de dockers. J'ai donc créé un docker network create lambda-local
réseau et modifié mes commandes de démarrage en:
sam local start-api --docker-network lambda-local
et
docker run -v "$PWD":/dynamodb_local_db -p 8000:8000 --network=lambda-local cnadiminti/dynamodb-local:latest
mais toujours recevoir la même erreur
sam local est en train d'imprimer 2018/02/22 11:12:51 Connecting container 98b19370ab92f3378ce380e9c840177905a49fc986597fef9ef589e624b4eac3 to network lambda-local
Je crée le dynamodbclient en utilisant:
const AWS = require('aws-sdk')
const dynamodbURL = process.env.dynamodbURL || 'http://0.0.0.0:8000'
const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID || '1234567'
const awsAccessKey = process.env.AWS_SECRET_ACCESS_KEY || '7654321'
const awsRegion = process.env.AWS_REGION || 'eu-west-2'
console.log(awsRegion, 'initialising dynamodb in region: ')
let dynamoDbClient
const makeClient = () => {
dynamoDbClient = new AWS.DynamoDB.DocumentClient({
endpoint: dynamodbURL,
accessKeyId: awsAccessKeyId,
secretAccessKey: awsAccessKey,
region: awsRegion
})
return dynamoDbClient
}
module.exports = {
connect: () => dynamoDbClient || makeClient()
}
et inspecter le dynamodbclient mon code crée des spectacles
DocumentClient {
options:
{ endpoint: 'http://0.0.0.0:8000',
accessKeyId: 'my-key',
secretAccessKey: 'my-secret',
region: 'eu-west-2',
attrValue: 'S8' },
service:
Service {
config:
Config {
credentials: [Object],
credentialProvider: [Object],
region: 'eu-west-2',
logger: null,
apiVersions: {},
apiVersion: null,
endpoint: 'http://0.0.0.0:8000',
httpOptions: [Object],
maxRetries: undefined,
maxRedirects: 10,
paramValidation: true,
sslEnabled: true,
s3ForcePathStyle: false,
s3BucketEndpoint: false,
s3DisableBodySigning: true,
computeChecksums: true,
convertResponseTypes: true,
correctClockSkew: false,
customUserAgent: null,
dynamoDbCrc32: true,
systemClockOffset: 0,
signatureVersion: null,
signatureCache: true,
retryDelayOptions: {},
useAccelerateEndpoint: false,
accessKeyId: 'my-key',
secretAccessKey: 'my-secret' },
endpoint:
Endpoint {
protocol: 'http:',
Host: '0.0.0.0:8000',
port: 8000,
hostname: '0.0.0.0',
pathname: '/',
path: '/',
href: 'http://0.0.0.0:8000/' },
_clientId: 1 },
attrValue: 'S8' }
Cette configuration doit-elle fonctionner? Comment puis-je les amener à se parler?
---- modifier ----
D'après une conversation sur Twitter, il est utile de mentionner (peut-être) que je peux interagir avec dynamodb au niveau de la CLI et du Web Shell
Merci beaucoup à Heitor Lessa qui m'a répondu sur Twitter avec un exemple de repo
Ce qui m'a dirigé vers la réponse ...
le conteneur de menu fixe de dynamodb est sur 127.0.0.1 dans le contexte de ma machine .__ (c'est pourquoi je pourrais interagir avec lui)
Le conteneur de menu fixe de SAM local est sur 127.0.0.1 dans le contexte de ma machine
Mais ils ne sont pas sur 127.0.0.1 du contexte de l'autre
Donc: https://github.com/heitorlessa/sam-local-python-hot-reloading/blob/master/users/users.py#L14
M'a indiqué de changer mon code de connexion pour:
const AWS = require('aws-sdk')
const awsRegion = process.env.AWS_REGION || 'eu-west-2'
let dynamoDbClient
const makeClient = () => {
const options = {
region: awsRegion
}
if(process.env.AWS_SAM_LOCAL) {
options.endpoint = 'http://dynamodb:8000'
}
dynamoDbClient = new AWS.DynamoDB.DocumentClient(options)
return dynamoDbClient
}
module.exports = {
connect: () => dynamoDbClient || makeClient()
}
avec les lignes importantes étant:
if(process.env.AWS_SAM_LOCAL) {
options.endpoint = 'http://dynamodb:8000'
}
du contexte du conteneur du docker local SAM, le conteneur dynamodb est exposé via son nom
Mes deux commandes de démarrage ont fini comme:
docker run -d -v "$PWD":/dynamodb_local_db -p 8000:8000 --network lambda-local --name dynamodb cnadiminti/dynamodb-local
et
AWS_REGION=eu-west-2 sam local start-api --docker-network lambda-local
avec le seul changement ici étant de donner un nom au conteneur dynamodb
Si vous utilisez sam-local sur un mac comme beaucoup de devs, vous devriez pouvoir utiliser
options.endpoint = "http://docker.for.mac.localhost:8000"
Ou sur les nouvelles installations de docker https://docs.docker.com/docker-for-mac/release-notes/#docker-community-edition-18030-ce-mac59-2018-03-26
options.endpoint = "http://Host.docker.internal:8000"
Au lieu d'avoir à faire plusieurs commandes comme Paul a montré ci-dessus (mais cela pourrait être plus agnostique de plate-forme?).
Comme @Paul l’a mentionné, il s’agit de configurer votre réseau entre les conteneurs de menu fixe - lambda et base de données.
Une autre approche qui a fonctionné pour moi (en utilisant docker-compose).
docker-compose:
version: '2.1'
services:
db:
image: ...
ports:
- "3306:3306"
networks:
- my_network
environment:
...
volumes:
...
networks:
my_network:
Ensuite, après docker-compose up
, exécuter docker network ls
affichera:
NETWORK ID NAME DRIVER SCOPE
7eb440d5c0e6 dev_my_network bridge local
Mon nom de conteneur de menu fixe est dev_db_1
.
Mon code js est:
const connection = mysql.createConnection({
Host: "dev_db_1",
port: 3306,
...
});
Ensuite, en exécutant la commande sam
:
sam local invoke --docker-network dev_my_network -e my.json
Empiler: